希腊字符转换

时间:2017-12-26 14:50:19

标签: c unicode character

我试图通过改变元音的音调,在c中制作一个简单的古希腊语到现代希腊语转换器。例如,用户在希腊语中键入一个文本,该文本具有以下字符:ῶ(unicode:U + 1FF6),因此程序将其转换为:ώ(unicode:U + 1F7D)。希腊人并不喜欢c,所以我不知道如何让它发挥作用。有任何想法吗?

2 个答案:

答案 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,在那里进行转换,最后转换回任何输出字符集。不幸的是,这个问题没有标记,所以这不在这个特定问题之内。

以上示例使用简单的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。

那就是它。祝你好运!