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

MSVC UTF8 string encoding uses incorrect code points

本文关键字:不正确 代码 UTF8 字符串 编码 MSVC      更新时间:2023-10-16

我正在尝试写字符"Ā"(https://www.fileformat.info/info/unicode/char/0100/index.htm)转换为C++11 UTF8字符串(使用u8前缀(。

const char *const utf8 = u8"Ā";
const char *const utf8_2 = u8"u0100";
const char *const chars = "Ā";
const int utf8_len = strlen(utf8);
const int utf8_2_len = strlen(utf8_2);
const int chars_len = strlen(chars);

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

utf8_len == 5
utf8_2_len = 2;
chars_len = 2;

其中:

utf8 == "Ä€"
utf8_2 == "Ä€"
chars == "Ä€"

源文件设置为UTF8(不带BOM表(。

尝试同样的Clang和GCC工作如预期:

https://godbolt.org/z/PNZFCa

有人知道为什么会发生这种行为吗?为什么前缀为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
...

如果不想与BOM一起保存,请使用/source-charset:UTF-8/utf-8

以UTF-8保存的测试代码,不带BOM:

#include <stdio.h>
#include <string.h>
int main()
{
const char *const utf8 = u8"Ā";
printf("%zun",strlen(utf8));
}

输出:

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