在ICU中打印UTF-8字符串

时间:2014-10-16 12:01:30

标签: c string encoding utf-8 icu

我最近发现了ICU的ustdio.h并认为测试会很有趣。没过多久就发现事情不太对劲。

Python 3在其字符串文字中支持UTF-8,因此像

这样的语句
print("90°")

有效。

ICU(在C API中)提供u_printf()u_printf_u(),后者设计用于系统实现中的UChar,但至少是UTF-16。

在尝试测试时,我尝试打印出一个特殊字符,即度数符号。

u_printf("90%c\n", 0xB0);

打印90�,如下所示:

u_printf(u8"90%c\n", 0xB0);
u_printf("90°\n");
u_printf(u8"90°\n");
u_printf_u(u"90%c\n", 0x00B0);

但是,实际上声明UTF-16字符串文字中的字符会得到所需的结果。

u_printf_u(u"90°\n");

$ ./a.out
90°

我可以坚持这一点,但我想要符合UTF-8标准;它似乎是一个优越的系统。为什么C11的UTF-8字符串文字与ICU的u_printf()不兼容?

1 个答案:

答案 0 :(得分:0)

我能够通过创建一个包含Unicode字符的字符串文字来导航问题,并将其作为char *参数传递给printf()

以下代码四次打印行José 90°\n

char *s = u8"José 90°";
for (int i = 0; i < strlen(s); ++i)
    putchar(s[i]);
putchar('\n');
printf("%s\n", s);
u_printf("%s\n", s);

UErrorCode error = U_ZERO_ERROR;
u_init(&error);
UChar *s16 = malloc(256*sizeof(UChar));
u_strFromUTF8(s16, 256, NULL, s, strlen(s), &error);
u_printf_u(u"%S\n", s16);

free(s16);

缓冲区s16可与u_strToUTF8()一起使用,以便成功返回并与UTF-8功能兼容。 ICU中的内部东西似乎更喜欢UTF-16(我猜它更容易解析),因此在转换回UTF-8返回调用者之前,你需要转换为它。