C++ C++;u8文字-Windows上的意外编码

C++ C++;u8文字-Windows上的意外编码,c++,utf-8,c++17,C++,Utf 8,C++17,我肯定这里缺少了一些东西,但我正在比较常规字符串文字(在utf8编码文档中)与u8字符串文字的内容,在Windows上,u8编码文字不包含预期的utf8编码数据,而在Linux上则包含 详情: cpp文件是utf8编码的 C++17已启用 在Windows上使用VS2019编译 在Linux上使用gcc 9.2.1编译 代码如下: #包括 #包括 结构HexCharStruct{ 无符号字符c; HexCharStruct(无符号字符c):c(_c){ }; 内联std::ostream&o

我肯定这里缺少了一些东西,但我正在比较常规字符串文字(在utf8编码文档中)与u8字符串文字的内容,在Windows上,u8编码文字不包含预期的utf8编码数据,而在Linux上则包含

详情:

  • cpp文件是utf8编码的
  • C++17已启用
  • 在Windows上使用VS2019编译
  • 在Linux上使用gcc 9.2.1编译
代码如下:

#包括
#包括
结构HexCharStruct{
无符号字符c;
HexCharStruct(无符号字符c):c(_c){
};

内联std::ostream&operatorMicrosoft编译器假定源代码是ANSI编码的,这取决于使用的Windows的本地化版本。在美国和西欧窗口上,假设编码为is
Windows-1252

当编译器假定
Windows-1252
时,它会对源代码中以错误编码编码的
UTF-8
字节进行解码,并认为它是四个
Windows-1252
字符,然后以UTF-8编码这些字符。快速演示(Python):


>>”看起来像utf8字符串的双utf8转换。字符U+00F0是以UTF-8编码的字节0xC3 0xB0。您的编译器将u8字符串视为内容采用CP-1252或拉丁语-1或其他单字节字符编码,并将其转换为UTF-8。在Linux上的
g++
中,UTF-8支持似乎不再是一个问题,但在Windows上的VS中仍然是一个问题。曾经对我有用的东西(不管每个系统):UTF-8序列编码为八进制序列:例如,U+00F0的
“\303\260”
(并且默默地假设
std::string
永远不会包含UTF-8以外的任何内容)。这在过去和现在都有效。(但是,我年纪大了,不能灵活地采用新功能……;-)尝试使用BOM将源文件保存为UTF-8。如果没有BOM表,编译器将采用系统默认代码页。或者,对于最新的MSVC版本,请使用“谢谢”以获得答案。继续讨论一下。因此,在这种情况下,编译器假定u8文本是Windows-1252编码的,但正确地假定所有正常字符串文本都是utf8编码的。因此,如果文档在Windows上是utf8编码的,并且使用的文本包含utf8字符,则假定编码正确,但如果要使用u8文本说明符,则需要/utf-8编译器标志。似乎是个bug,编译器标志只是绕过了它。@aa在您的示例中,
s1
将包含源代码中编码的字节。编译器在读取源代码时采用编码,在创建
“…”字符串时采用相同的编码。
L“…”
u8“…”
字符串必须使用假定或指定的源编码将源字节解码为Unicode代码点,然后分别将这些代码点编码为UTF-16/UTF-32(Windows/Linux)或UTF-8,因此如果源编码不正确,则会得到不正确的结果。