显示扩展的ASCII字符

use*_*234 8 c++ windows x86 visual-studio-2005

在32位Windows上的Visual Studio 2005中,为什么我的控制台不显示128到255之间的字符?

例如:

cout << "¿" << endl;  //inverted question mark
Run Code Online (Sandbox Code Playgroud)

输出:

?
Press any key to continue . . .
Run Code Online (Sandbox Code Playgroud)

Che*_*Alf 13

Windows 控制台窗口是纯Unicode.它的缓冲区将文本存储为UCS-2 Unicode(每个字符16位,基本上类似于原始Unicode,对现代21位Unicode 的基本多语言平面的限制).因此,控制台窗口可以呈现几乎所有类型的文本.

但是,对于每个字符的单字节(并且可能还有一些可变长度编码),i/o Windows会自动转换为控制台窗口的活动代码页.如果控制台窗口是[cmd.exe]实例,那么您可以通过命令检查该实例chcp,更改代码页的缩写.像这样:

C:\test> chcp
Active code page: 850

C:\test> _

代码页850是基于原始IBM PC英文代码页437的编码.对于至少挪威PC的控制台窗口,850是默认的(尽管精明的挪威人可以将其改变为865).但是,这些都不是您应该使用的代码页.

最初的IBM PC代码页(字符编码)被称为OEM,这是一个毫无意义的缩写,原始设备制造商.它具有适合原始PC文本模式屏幕的漂亮的线条绘制字符.更一般地,OEM表示控制台窗口的默认代码页,其中代码页437只是原始代码页:它可以被配置,例如每个窗口通过chcp.

当Microsoft创建16位Windows时,他们选择Windows中称为ANSI的另一种编码.最初的一个是ISO Latin-1的扩展,很长一段时间是互联网的默认设置(但是,目前还不清楚哪个是第一个:微软参与了标准化).这个原始ANSI现在称为Windows ANSI Western.

ANSI是几乎所有其他Windows使用的非Unicode代码页.控制台窗口使用OEM.记事本,其他编辑器等使用ANSI.

然后,当微软制造Windows 32位时,他们采用了名为Unicode的Latin-1的16位扩展.Microsoft是Unicode Consortium的原始创始成员.并且基本API(包括控制台窗口,文件系统等)被重写为使用Unicode.为了向后兼容,有一个转换层可以在控制台窗口的OEM和Unicode之间进行转换,在ANSI和Unicode之间转换其他功能.例如,MessageBoxA是基于Unicode的ANSI包装器MessageBoxW.

实际的结果是,在Windows中,您的C++源代码通常使用ANSI编码,而控制台窗口则采用OEM.例如,哪个

cout << "I like Norwegian blåbærsyltetøy!" << endl;
Run Code Online (Sandbox Code Playgroud)

生成纯gobbledegook ...您可以使用基于Unicode的控制台窗口API将Unicode直接输出到控制台窗口,避免转换,但这很尴尬.

请注意,使用wcoutcout不是帮助:按设计wcout只是从宽字符串转换为程序的窄字符集,在途中丢​​弃信息.令人难以置信的是,C++标准库提供了相当大的非常复杂的功能块,这些功能毫无意义(因为这些转换可能只是得到了支持cout).但它就是这样,毫无意义.也许这是一些政治类的妥协,但无论如何,wcout没有帮助,即使如果它在某些方面是有意义的,然后它"应该"在逻辑上这方面的帮助.

那么挪威新手程序员如何获得例如"blåbærsyltetøy"?

好吧,只需将活动代码页更改为ANSI即可.由于在大多数西方国家/地区的PC上,ANSI是代码页1252,因此您可以为给定的命令解释器实例执行此操作

C:\test> chcp 1252
Active code page: 1252

C:\test> _

现在,像如[edit.com(仍然存在于Windows XP中!)老的DOS程序都会产生一些官样文章,因为原来的PC字符集白描人物是不存在的ANSI,因为国家字符在ANSI不同的代码.但嘿,谁使用旧的DOS程序?不是我!

如果您希望将其作为更永久的代码页,则必须通过未记录的注册表项更改控制台窗口的配置:

HKEY_LOCAL_MACHINE \系统\ CurrentControlSet \控制\ NLS \代码页

在此键中,将值更改OEMCP为1252,然后重新启动.

chcp1252的代码页的其他更改一样,使旧的DOS程序呈现gobbledegook,但使C++程序或其他现代控制台程序正常工作.

因为您在控制台窗口中具有与Windows其余部分中相同的字符编码.