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

C++ 如何正确初始化宽字符串?,c++,c,string,char,C++,C,String,Char,我试图找出c中的宽字符。例如,我测试了一个字符串,该字符串包含一个在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},相反,它包含一个额外的字符,在我看来这只是浪费了空间

我试图找出c中的宽字符。例如,我测试了一个字符串,该字符串包含一个在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},相反,它包含一个额外的字符,在我看来这只是浪费了空间。有人能帮我理解这是怎么回事吗?

你在这里所做的就是莫吉贝克。您的源代码是用UTF-8编写的,但它是在Windows代码页1252中解释的(即编译器源字符集是CP1252)

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

wchar_t* T2 = L"\x112";



<> >更大的问题是,我所知的C和C++都没有一种机制来指定代码本身中的源字符集,所以它总是一个可以轻松复制粘贴的东西的设置或选项。

< p>编译器错误地解释了作为WOLTF-1252的源代码文件(保存为UTF-8)。(通常称为ANSI)。它不会将字节序列
C492
解释为一个字符的UTF-8字符串“Ē”,而是解释为两个字符的Windows-1252字符串
“Ä”
“Ä”
的unicode码点是U+00C4,unicode码点是
“。”
为U+2019。这正是您在宽字符串中看到的内容

8位字符串只起作用,因为对字符串的错误解释无关紧要,因为它在编译过程中不会转换。编译器将字符串读取为Windows-1252,并将字符串发出为Windows-1252(因此它不需要转换任何内容,并将两者都视为“Ä”)您将二进制代码中的源代码和数据解释为UTF-8,因此您认为两者都是<代码>“<”/>代码>

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


顺便说一句:在宽字符串中观察到的正确UTF-16编码(MSVC用于宽字符串的编码)不是
{0xc492,0x0000}
,而是
{0x0112,0x0000}
,因为
“Ē
U+0112

哪个编码用于保存源文件?如果有的话,我希望第二个数组是{0x0112,0x0000},这是utf-16或utf-32编码。我不知道是什么编码{0x00c4,0x2019,0x0000}应该在中。字符0xC492看起来也是这样,请注意字符串文字是
const
字符的数组。您的代码正在使用从字符串文字到指向字符指针的不推荐的转换。这仅用于与C向后兼容的原因,并在C++11中删除。不要这样做。st环文字不能修改。让你的指针指向“代码> const 字符……而且,这甚至会编译的事实表明你必须使用一个古老的编译器。你可能想考虑升级…更简单的方法是将文件保存为带有BOM的UTF-8,而不是用十六进制转义来保存。”N.M.最简单的方法是:o确保代码在任何地方都不起作用…请找到一个默认情况下不起作用的实现。@AnttiHaapala除了在MSVC中之外,其他地方都不起作用。MSVC通过BOM的存在来检测UTF-8编码的源文件是有文档记录的行为。但您仍然认为这不符合UTF-8标准(不允许忽略文件开头的U+FEFF字符(BOM)以及ANSI C(将文件开头的U+FEFF定义为语法错误)@n.m.好的,那么你是不正确的。BOM被Clang和GCC忽略,而不是被TCC忽略,因为它会导致语法错误。也就是说,只有MSVC会产生任何影响。GCC和Clang使用UTF-8作为源字符集,除非区域设置另有提示,在这种情况下,他们会忽略BOM。
wchar_t* T2 = L"\u0112";