【发布时间】:2019-10-27 15:46: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 进行同样的尝试可以按预期工作:
有谁知道为什么会发生这种行为?为什么 u8 前缀的 Unicode 字符被编码为 5 个字节(应该是 2 个字节)?
【问题讨论】:
-
可能是编译器错误。您是否考虑过举报?
-
我的猜测是,它被双重编码。首先,文本编辑器将
Ā编码为两个字节"Ä€",然后编译器将其作为两个字符的Latin-1 字符串并进一步将每个字符编码为UTF-8。尝试将 .cpp 文件保存为“带签名的 UTF-8”,这样编译器就知道将源代码读取为 UTF-8 而不是 Latin-1。 -
@IgorTandetnik 使用 UTF8 BOM 保存确实可以解决此问题。在这种情况下,我认为这是一个编译器错误,所以我会报告它。
-
这不是错误。大多数 Windows 程序假定文件是 ANSI 编码的,以便与旧版 Windows 使用向后兼容,并且需要 UTF-8 w/ BOM 来区分。
-
这是一个合法的选择,但它仍然是一个 some 编码的文本文件,没有说明编码是什么。它“只是一堆字节”。大多数 Windows 程序,包括 MSVC 编译器,都假定文件的编码是本地化的 ANSI 编码,除非有 BOM。以字节 EF BB BF(以 UTF-8 编码的 U+FEFF Unicode BOM 字符)开头的文件是 UTF-8 文件。如果它以
FF FE开头,则它是一个 UTF-16LE 编码的文件,等等。没有 BOM,编译器假定为 ANSI。这就是/source-charset:开关存在的原因。
标签: c++ c++11 visual-c++ unicode