[英]MSVC is double-encoding UTF-8 strings, why?
所以,这里有一些简单的代码来重现我的问题:
#include <cstdio>
const char* badString = u8"aš𒀀";
const char* anotherBadString = u8"\xef\x96\xae\xef\x96\xb6\x61\xc5\xa1\xf0\x92\x80\x80";
const char* goodString = "\xef\x96\xae\xef\x96\xb6\x61\xc5\xa1\xf0\x92\x80\x80";
void printHex(const char* str)
{
for (; *str; ++str)
{
printf("%02X ", *str & 0xFF);
}
puts("");
}
int main(int argc, char *argv[])
{
printHex(badString);
printHex(anotherBadString);
printHex(goodString);
return 0;
}
我希望所有这些字符串都打印出相同的结果, EF 96 AE EF 96 B6 61 C5 A1 F0 92 80 80
。 但是,在 MSVC 2019 中,前两个字符串打印出C3 AF C2 96 C2 AE C3 AF C2 96 C2 B6 61 C3 85 C2 A1 C3 B0 C2 92 C2 80 C2 80
。 这似乎是额外编码为 UTF-8 的结果。
我在其他线程中读到这个问题的解决方案是将/utf-8
标志添加到项目中,但我已经尝试过,它没有任何区别。 有没有我在这里不理解的更基本的东西?
谢谢一堆!
第一个字符串的第一个字符是ï
(U+00EF,带分音符的拉丁小写字母 I),其 UTF-8 编码为C3 AF
。
您显然希望第一个字符串以 U+F5AE 开头,但是您打开源文件的任何编辑器都与 MSVC 一致,即它不以该字符开头。
源文件可能编码为带有BOM 的UTF-8 ,这就是/utf-8
标志不会改变任何内容的原因。 字符串在某个时候被破坏了,现在它被破坏的形式在文件中忠实地表示出来,MSVC 忠实地将它保存在编译代码中。
第二个字符串以\\xef
,MSVC 将其解释为等效于\ï
,这又是ï
。 我在 C++20 草案标准中找不到任何关于\\x
在 UTF-8 字符串中应该意味着什么的明确声明(尽管我看起来不是很努力)。 根据实验,似乎除 MSVC 之外的大多数编译器将\\x
后跟十六进制数字视为文字字节,即使这会使字符串无效 UTF-8。 我认为您不应该在u8
前缀字符串中使用\\x
,因为它不可移植(除了\\x00
到\\x7f
,可能)。 如果你想要 U+F5AE 然后写\
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.