我最近发现了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()
不兼容?
答案 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返回调用者之前,你需要转换为它。