【问题标题】:How do I represent a Unicode character in a literal string ISO/ANSI C when the character set is ASCII?当字符集为 ASCII 时,如何在文字字符串 ISO/ANSI C 中表示 Unicode 字符?
【发布时间】:2009-09-14 14:12:51
【问题描述】:

在 Perl 中,我可以说

my $s = "r\x{e9}sum\x{e9}";

"résumé" 分配给$s。我想在C中做类似的事情。具体来说,我想说

sometype_that_can_hold_utf8 c = get_utf8_char();
if (c < '\x{e9}') {
    /* do something */
}

【问题讨论】:

    标签: c unicode


    【解决方案1】:

    对于 UTF8,您必须使用找到的规则自己生成编码,例如 here。例如,德语的 s (ß, 代码点 0xdf) 的 UTF8 编码为 0xc3,0x9f。您的 e-acute(é,代码点 0xe9)的 UTF8 编码为 0xc3,0xa9。

    您可以在字符串中添加任意十六进制字符:

    char *cv = "r\xc3\xa9sum\xc3\xa9";
    char *sharpS = "\xc3\x9f";
    

    【讨论】:

    • 如果变量的宽度足以容纳 UTF-16,你能说 \x00e9 吗?
    【解决方案2】:

    如果您有 C99 编译器,则可以使用 (和 )并直接在源代码中输入 Unicode 代码点。

    $ cat wc.c

    #include <locale.h>
    #include <stdio.h>
    #include <wchar.h>
    
    int main(void) {
      const wchar_t *name = L"r\u00e9sum\u00e9";
      setlocale(LC_CTYPE, "en_US.UTF-8");
      wprintf(L"name is %ls\n", name);
      return 0;
    }
    

    $ /usr/bin/gcc -std=c99 -pedantic -Wall wc.c

    $ ./a.out

    name is résumé
    

    【讨论】:

    • 虽然上面的代码确实有效,但最重要的是要提到wchar_t 不一定能够同时表示多个语言环境。它只需要足够宽以支持当前的语言环境。
    • “足以支持当前语言环境”即MB_CUR_MAXsize_t __ctype_get_mb_cur_max()
    【解决方案3】:

    【讨论】:

    • 请记住,这是一个 UNIX 规范 (SUS),不是 ISO C 的一部分。我之所以提出它,是因为问题上没有 unix 标记。
    • 我对如何在 C 中以 ASCII 文本呈现 é 更感兴趣,在 Perl 中我可以通过说 "\x{e9}" 来实现。问题是源是ASCII,但是需要创建UTF-8字符。
    • @Chas:为什么不使用 UTF-8 作为源文件编码?只要多字节序列只出现在字符串文字中,大多数编译器就不应该有任何问题......
    • 因为源代码正在通过一个要求它是 7 位干净的系统。我很高兴我不必使用三元组(例如??= 代表#)。请注意,源代码正在通过该系统,而不是在那里编译。是的,我知道这很愚蠢。
    【解决方案4】:

    wchar_tsetlocale() 似乎可选

    #include <stdio.h>
    
    int main(void) {
      const char *const name = "r\u00e9sum\u00e9";
      printf("name is %s\n",name);
      return 0;
    }
    
    $ echo $LANG
    en_US.UTF-8
    $ /usr/bin/gcc -std=c99 -pedantic -Wall -Wextra bc.c
    $ ./a.out
    name is résumé
    

    【讨论】:

      猜你喜欢
      • 2011-03-09
      • 2011-06-09
      • 2013-08-21
      • 1970-01-01
      • 1970-01-01
      • 2010-09-17
      • 2010-09-11
      • 1970-01-01
      • 2013-02-05
      相关资源
      最近更新 更多