在C语言中将通用字符名称(UCN)转换为UTF-8的问题
问题:通用字符名称(UCN)转UTF-8编码的实现困惑
需要将数据库中的通用字符名称(UCN)数据转换为UTF-8编码,比如把字符串Düsseldorf转换为Düsseldorf,尝试多种代码后仍未找到正确方法,具体尝试过程如下:
尝试1:char字符串直接使用UCN
char str[] = "\u00c3\u00bc"; // 对应ü size_t str_len = strlen(str); for (i = 0; i < str_len; i++) printf("%02hhx ", str[i]); printf("- %zu - %s\n", str_len, str); // 输出 "c3 83 c2 bc - 4 - ü"
结果:c3是正确的,但后续3字节不符合预期,编译器仅识别UCN的第一部分(\u00c3)。
尝试2:宽字符串使用UCN
wchar_t wcs[] = L"\u00c3\u00bc"; size_t wcs_len = wcslen(wcs); for (i = 0; i < wcs_len; i++) printf("%02hhx ", wcs[i]); printf("- %zu - %ls\n", wcs_len, wcs); // 输出 "c3 bc - 2 - ü"
结果:完整识别了UCN(c3 bc),但仍未输出ü。
尝试3:使用十六进制编码的char字符串
char str[] = "\xc3\xbc"; size_t str_len = strlen(str); for (i = 0; i < str_len; i++) printf("%02hhx ", str[i]); printf("- %zu %s\n", str_len, str); // 输出 "c3 bc - 2 ü"
结果:能输出ü,但已经将UCN改为了十六进制编码,不符合需求。
疑问:如何实现从\u00c3\u00bc转换为ü?
更新内容
正如Rob Napier所述,初始字符串字面量存在双重编码问题:\u00c3\u00bc本身是UTF-8编码ü(即\u00fc)的字节序列被错误当作UCN解析,导致出现编码混乱。
目前可行的解决方式只有手动修正字符串字面量:
- 直接写成
"Düsseldorf" - 或者使用正确的UCN:
"D\u00fcsseldorf"
另外,"D\xc3\xbcsseldorf"能得到正确结果只是巧合——因为\xbc后的s是非十六进制字符,编译器会停止解析十六进制序列;但如果是"AAA\xc3\xbcBBB",会输出"AAAû"(对应字节0x41 0x41 0x41 0xc3 0xbb),因为\x会持续读取后续的十六进制字符,直到遇到非十六进制字符为止,这种方式不可靠。
内容的提问来源于stack exchange,提问作者geohei
相关产品推荐
相关产品推荐

