如何正确初始化宽字符串?

时间:2019-04-22 13:26:17

标签: c++ c string char

我试图找出c中的宽字符。例如,我测试了一个包含单个字母“ a”的字符串,该字符串在utf8中编码为c492。

char* T1 = "Ē";
//This is the resulting array { 0xc4, 0x92, 0x00 }

wchar_t* T2 = L"Ē";
//This is the resulting array { 0x00c4, 0x2019, 0x0000 }

我希望第二个数组为{0xc492,0x0000},相反,它包含一个多余的字符,我认为这只是浪费空间。谁能帮助我了解这是怎么回事?

2 个答案:

答案 0 :(得分:6)

您在这里要做的就是mojibake。您的源代码是用UTF-8编写的,但是在Windows代码页1252中被解释了(即,编译器源字符集为CP1252 )。

宽字符串内容是转换为UCS-2的UTF-8字节0xC4 0x92的 Windows代码页1252 字符。 最简单的出路是改用转义符:

wchar_t* T2 = L"\x112";

wchar_t* T2 = L"\u0112";

更大的问题是,据我所知,C和C ++都没有一种在代码本身内指定源字符集的机制,因此,它始终是可以轻松复制粘贴的外部设置或选项。

答案 1 :(得分:3)

您的编译器将您的源代码文件(保存为UTF-8)误解为Windows-1252(通常称为ANSI)。它不会将字节序列C4 92解释为单字符UTF-8字符串“Ē”,而是解释为两个字符的Windows-1252字符串"Ä’""Ä"的统一代码点为U + 00C4,"’"的统一代码点为U + 2019。这正是您在宽字符串中看到的。

8位字符串仅起作用,因为对该字符串的错误解释并不重要,因为在编译过程中不会对其进行转换。编译器将字符串作为Windows-1252读取,并将字符串作为Windows-1252发出(因此,它无需转换任何内容,并且都将其视为“Ä’”)。您将源代码和二进制文件中的数据解释为UTF-8,因此您将两者都视为"Ē"

要让编译器将您的源代码视为UTF-8,请使用开关/utf-8

BTW:在宽字符字符串中观察到的正确UTF-16编码(MSVC用于宽字符串的编码)不是 {0xc492, 0x0000},而是{{ 1}},因为{0x0112, 0x0000}"Ē"

相关问题