我试图通过改变元音的音调,在c中制作一个简单的古希腊语到现代希腊语转换器。例如,用户在希腊语中键入一个文本,该文本具有以下字符:ῶ(unicode:U + 1FF6),因此程序将其转换为:ώ(unicode:U + 1F7D)。希腊人并不喜欢c,所以我不知道如何让它发挥作用。有任何想法吗?
答案 0 :(得分:2)
假设您使用了理智的操作系统(意思是Windows,而不是Windows),使用C99 / C11语言环境和广泛的字符支持很容易实现。考虑 filter.c :
#include <stdlib.h>
#include <locale.h>
#include <wchar.h>
#include <stdio.h>
wint_t convert(const wint_t wc)
{
switch (wc) {
case L'ῶ': return L'ώ';
default: return wc;
}
}
int main(void)
{
wint_t wc;
if (!setlocale(LC_ALL, "")) {
fprintf(stderr, "Current locale is unsupported.\n");
return EXIT_FAILURE;
}
if (fwide(stdin, 1) <= 0) {
fprintf(stderr, "Standard input does not support wide characters.\n");
return EXIT_FAILURE;
}
if (fwide(stdout, 1) <= 0) {
fprintf(stderr, "Standard output does not support wide characters.\n");
return EXIT_FAILURE;
}
while ((wc = fgetwc(stdin)) != WEOF)
fputwc(convert(wc), stdout);
return EXIT_SUCCESS;
}
上述程序读取标准输入,将每个ῶ
转换为ώ
,然后输出结果。
请注意,宽字符串和字符的前缀为L
; L'ῶ'
是一个宽字符常量。如果执行字符集(编译代码的字符集)是Unicode,则这些仅在Unicode中,这取决于您的开发环境。 (幸运的是,在Windows之外,UTF-8现在几乎是一个标准 - and that is a good thing - 所以代码如上所述Just Works。)
在POSIXy系统(如Linux,Android,Mac OS,BSD)上,您可以使用iconv()
工具从任何输入字符集转换为Unicode,在那里进行转换,最后转换回任何输出字符集。不幸的是,这个问题没有标记posix,所以这不在这个特定问题之内。
以上示例使用简单的switch / case语句。如果有许多替换对,可以使用例如。
typedef struct {
wint_t from;
wint_t to;
} widepair;
static widepair replace[] = {
{ L'ῶ', L'ώ' },
/* Others? */
};
#define NUM_REPLACE (sizeof replace / sizeof replace[0])
并在运行时,排序replace[]
(使用qsort()
和比较from
元素的函数),并使用二进制搜索快速确定是否要替换宽字符(如果是这样,哪个广泛的人物)。因为这是 O(log 2 N)操作,其中 N 是对的数量,并且它利用缓存可以,甚至成千上万的替换这样对不是问题。 (当然,您也可以在运行时构建替换数组,即使是来自用户输入或命令行选项。)
对于Unicode字符,我们可以使用uint32_t map_to[0x110000];
直接将每个代码点映射到另一个Unicode代码点,但由于我们不知道宽字符是否是Unicode,我们不能这样做;在编译时间之前我们不知道宽字符的代码范围。当然,我们可以进行多阶段编译,测试程序生成上面显示的replace[]
数组,并输出十进制代码;然后进行某种自动分组或聚类,例如位图或散列表,以便做到更快&#34;。
然而,在实践中,通常会发现I / O(读取和写入数据)比转换本身花费更多的实际时间。即使转换是瓶颈,转换率对大多数人来说也是足够的。 (例如,在使用GNU实用程序编译C或C ++代码时,预处理器首先在内部将源代码转换为UTF-8。)
答案 1 :(得分:1)
好的,这里有一些快速的建议。我不会使用C because Unicode is not wel supported (yet)。
更好的语言选择是Python,Java,......,任何具有良好Unicode支持的东西。
我写了一个从标准输入读取并写入标准输出的实用程序。这使得从命令行和脚本中轻松使用。
我可能会遗漏一些东西,但它会是这样的(伪代码):
while ((inCharacter = getCharacterFromStandardInput) != EOF
{
switch (inCharacter)
{
case 'ῶ': outCharacter = ώ; break
...
}
writeCharacterToStandardOutput(outCharacter)
}
您还需要选择&amp;处理格式:UTF-8/16/32。
那就是它。祝你好运!