C++ 为什么带有中文代码页集的Windows控制台可以显示UTF-16编码字符?

C++ 为什么带有中文代码页集的Windows控制台可以显示UTF-16编码字符?,c++,visual-c++,unicode,locale,C++,Visual C++,Unicode,Locale,Per: 对于Microsoft C/C++编译器,源字符集和执行字符集都是ASCII C++03 2.1翻译阶段 “.不在基本源字符集中的任何源文件字符 (2.2)替换为通用字符名,该通用字符名指定 字符。(一个实现可以使用任何内部编码,只要 作为源文件中遇到的实际扩展字符,以及 源文件中表示的扩展字符与 处理通用字符名(即使用\uxxx表示法) 相当于。)” 2.13.2字符文字 通用字符名转换为编码,在 名为的字符的执行字符集。如果没有 编码时,通用字符名被转换为 实现定义的编码。” 为了

Per:

对于Microsoft C/C++编译器,源字符集和执行字符集都是ASCII

C++03

2.1翻译阶段

“.不在基本源字符集中的任何源文件字符 (2.2)替换为通用字符名,该通用字符名指定 字符。(一个实现可以使用任何内部编码,只要 作为源文件中遇到的实际扩展字符,以及 源文件中表示的扩展字符与 处理通用字符名(即使用\uxxx表示法) 相当于。)”

2.13.2字符文字

通用字符名转换为编码,在 名为的字符的执行字符集。如果没有 编码时,通用字符名被转换为 实现定义的编码。”

为了测试MSVC++使用的执行字符集,我编写了以下代码:

wchar_t *str = L"中";
unsigned char *p = reinterpret_cast<unsigned char*>(str);
for (int i = 0; i < sizeof(L"中"); ++i)
{
   printf ("%x ", *(p + i));
}
哪些产出:

我想知道的是,如果Windows控制台的区域设置(解码器)设置为非UTF-16(MS代码页936),如何对UTF-16编码的字符进行解码?怎么会这样

如果Windows控制台的区域设置(解码器)设置为非UTF-16,那么如何对UTF-16编码的字符进行解码

有两种方法可以将文本写入控制台。字节方式使用Win32 API
WriteConsoleA
,提供使用控制台代码页(“ANSI”)解释的字节中的字符。Unicode方式,
WriteConsoleW
,接收UTF-16LE字符串并直接将字符写入控制台,而不必担心它使用的是什么代码页

当输出为交互式控制台时,stdio函数
printf
使用
WriteConsoleA
。至少从VS2005开始,
wprintf
函数调用了
WriteConsoleW

,我想我明白了

<微软> C++ 2008(大概2005 +),CRT函数为<代码> WPROTFF ,<代码> WcOUT 实现,使它们转换为宽字符串文字为“代码> L”。中"以UTF-16编码,在引擎盖下,以匹配当前区域设置/代码页设置。因此这里发生的是
L“中“
转换为简体中文代码页936中的字节
D6 D0

我错了,
setlocale
设置控制台代码页。它只是设置了CRT函数在“转换”过程中使用的当前程序代码页。要更改控制台代码页,可以使用命令
chcp
或Win-API
setconsoleoputcp()


由于我的控制台的默认页面是936,因此可以正确显示该字符,而不存在任何问题。

如果控制台使用默认区域设置,即
“C”
,或者使用其他区域设置,例如
“English”
wprintf
将不会输出正确的字符
中“
。恐怕不是这样。您可以使用调试器并查看内存位置,以确定下面发生了什么。