Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ MSVC UTF8字符串编码使用了不正确的代码点_C++_C++11_Visual C++_Unicode - Fatal编程技术网

C++ MSVC UTF8字符串编码使用了不正确的代码点

C++ MSVC UTF8字符串编码使用了不正确的代码点,c++,c++11,visual-c++,unicode,C++,C++11,Visual C++,Unicode,我试图将字符“Ā”()写入C++11UTF8字符串(使用u8前缀) 在MSVC(16.2.4)下运行此操作将导致: utf8_len == 5 utf8_2_len = 2; chars_len = 2; 其中: utf8 == "Ä€" utf8_2 == "Ä€" chars == "Ä€" 源文件设置为UTF8(无BOM表) 尝试使用Clang和GCC进行相同的操作,效果与预期一样: 有人知道为什么会发生这种行为吗?为什么u8前缀Unicode字符被编码为5字节(当它应该是2字

我试图将字符“Ā”()写入C++11UTF8字符串(使用
u8
前缀)

在MSVC(16.2.4)下运行此操作将导致:

utf8_len == 5
utf8_2_len = 2;
chars_len = 2;
其中:

utf8 == "Ä€"
utf8_2 == "Ä€"
chars == "Ä€"
源文件设置为UTF8(无BOM表)

尝试使用Clang和GCC进行相同的操作,效果与预期一样:


有人知道为什么会发生这种行为吗?为什么
u8
前缀Unicode字符被编码为5字节(当它应该是2字节时)?

Microsoft编译器对没有BOM表的文件采用本地ANSI编码,在您的情况下可能是Windows-1252。如果从命令行运行
cl/?
,将看到以下命令行开关:

...
/source-charset:<iana-name>|.nnnn set source character set
/execution-charset:<iana-name>|.nnnn set execution character set
/utf-8 set source and execution character set to UTF-8
...
输出:
可能是编译器错误。你考虑过报告吗?我猜,它是双重编码的。首先,文本编辑器将
Ā
编码为两个字节
“Ä€”
,然后编译器将其作为两个字符的拉丁-1字符串,并进一步将每个字符编码为UTF-8。尝试将.cpp文件保存为“带签名的UTF-8”,以便编译器知道如何将源代码读取为UTF-8而不是拉丁语-1。@使用UTF8 BOM保存IgorTandetnik确实可以解决此问题。在这种情况下,我认为这是一个编译器错误,所以我会报告它。它不是一个错误。大多数Windows程序假定文件是ANSI编码的,以便与传统Windows用法向后兼容,并且需要UTF-8 w/BOM进行区分。这是一个合理的选择,但在某些编码中它仍然是一个文本文件,没有说明编码是什么。它“只是一堆字节”。大多数Windows程序,包括MSVC编译器,都假定文件的编码是本地化的ANSI编码,除非有BOM表。以字节EF BB BF(UTF-8中编码的U+FEFF Unicode BOM字符)开头的文件是UTF-8文件。如果它以
FF FE
开头,则它是一个UTF-16LE编码的文件,等等。没有BOM,编译器将采用ANSI。这就是为什么
/source字符集:
开关存在的原因。谢谢,但我使用了另存为(带编码)并选择了UTF-8(不带BOM)。所以我仍然相信这是一个bug。@MarkIngram BOM是告诉Windows程序一个文件是用UTF-8编码的元数据。没有它,它可以保存在Windows-1252或Windows-1251或UTF-8或任何其他编码中。除非另有说明,否则编译器采用ANSI编码(例如Windows版本的本地化编码…US Windows==Windows-1252)。
...
/source-charset:<iana-name>|.nnnn set source character set
/execution-charset:<iana-name>|.nnnn set execution character set
/utf-8 set source and execution character set to UTF-8
...
#include <stdio.h>
#include <string.h>

int main()
{
    const char *const utf8 = u8"Ā";
    printf("%zu\n",strlen(utf8));
}
C:\>cl /nologo test.cpp
test.cpp

C:\>test
5

C:\>cl /nologo /utf-8 test.cpp
test.cpp

C:\>test
2