c - 希腊字符转换

标签 c unicode character

我正在尝试通过改变元音的声调,在 c 中制作一个简单的 - 古希腊语到现代希腊语 - 转换器。例如,用户键入包含字符的希腊文文本:ῶ(unicode:U+1FF6),因此程序将其转换为:ώ(unicode:U+1F7D)。 c 不支持希腊语,所以我不知道如何让它工作。有任何想法吗?

最佳答案

假设您使用的是正常的操作系统(也就是说,不是 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 -- 所以像上面这样的代码就可以了。)

在 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(log2N) 操作,其中 N 是对的数量,并且它利用了缓存,甚至数千次替换这样对不是问题。 (当然,您也可以在运行时构建替换数组,甚至是通过用户输入或命令行选项。)

对于 Unicode 字符,我们可以使用 uint32_t map_to[0x110000]; 将每个码点直接映射到另一个 Unicode 码点,但是因为我们不知道宽字符是否是 Unicode,我们不能那样做;直到编译时我们才知道宽字符的代码范围。当然,我们可以进行多阶段编译,一个测试程序生成如上所示的replace[]数组,并以十进制形式输出它们的代码;然后进行某种自动分组或聚类,例如位图或哈希表,以“更快”地完成。

但是,在实践中通常会发现 I/O(读取和写入数据)比转换本身花费更多的实际时间。即使转换是瓶颈,转换率对大多数人来说也足够了。 (例如,当使用 GNU 实用程序编译 C 或 C++ 代码时,预处理器首先在内部将源代码转换为 UTF-8。)

关于c - 希腊字符转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47980182/

相关文章:

java - 用汉字声明字符串

c - 在枚举中使用实例化

c - 当我尝试以相反顺序打印字符串时,为什么我的 C 程序会打印新的空白行?

c - 初始化指向 null 的指针

c++ - 将字符串转换为Unicode,并将Unicode转换为十进制代码点(C++)

java - 在 Java 中使用 .substring 操作字符串

谁能确认我(欧拉法)对这些常微分方程的实现?

c# - 正则表达式未使用 Unicode 字符范围

macos - 在哪里可以找到 OSX 支持的所有表情符号的列表

php - 如何查找包含大写或小写非拉丁短语的结果? (PHP, MySQL)