实际上,这个问题只会在 Windows 中表现出来,所以我假设是 Windows。
那么问题是C++狭义扩展执行字符集(1)(编码)与控制台窗口使用的编码不匹配。“窄”是指char
类型。“执行字符集”是 C++ 标准采用的正式术语,指的是假定用于存储在可执行文件中的文本的编码。编译器将源代码文字转换为此编码。它还假设用于与任何外部编码的转换,例如与控制台编码的转换。

使用 Visual C++ 时,无论源代码编码如何,窄编码始终是Windows ANSI (2),除非您欺骗了编译器。假设您使用的是 Visual C++,那么这就是您知道的一种编码。
默认情况下,控制台窗口中的编码是用于原始 IBM PC 的编码,在您的情况下可能是代码页 850(原始 IBM PC 英语代码页 437 的西欧变体)。运行 Windows 命令解释器cmd
(Windows-key+ R、type cmd
、OK)。键入chcp
以检查当前代码页。键入chcp 1252
以切换到 Windows ANSI Western,这可能是您计算机上的 Windows ANSI 代码页。运行您的程序 [.exe] 文件,例如通过输入其完整路径,或转到其目录并仅输入其名称,例如
[H:\开发\测试\0046]
> cl /nologo /EHsc /GR encoding.cpp /Fe:b.exe
编码.cpp
[H:\开发\测试\0046]
> chcp & b
活动代码页:850
Höger elle vänster
höger
←这里没有输出,没有比较相等。
[H:\开发\测试\0046]
> chcp 1252
活动代码页:1252
[H:\开发\测试\0046]
>乙
Höger elle vänster
豪格
杜瓦尔德霍格
[H:\开发\测试\0046]
> _
... 其中cl
(原始“Lattice C”的缩写)是 Visual C++ 编译器。
您可以通过运行来更永久地更改控制台代码页regedit
,转到此注册表项:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage
并在右窗格的列表中双击名为OEMCP
(原始设备制造商代码页的缩写,指 IBM PC)的值,将其更改为 1252,或更一般地为与该值相同的ACP
值,然后重新启动机器.
哦,还需要将控制台窗口字体更改为TrueType 字体,例如 Lucida Console,因为默认是(模拟的)位图字体,只能在原始控制台代码页上正常工作。您可以右键单击控制台窗口标题以获取菜单,选择[默认],并配置默认字体、大小、颜色等。更改不会影响当前控制台窗口,但它们将应用于以后的控制台窗口,除了对于那些已经单独配置的(3)。
这种控制台窗口配置的替代方法是使用Console2程序。如果这样做,那么在 Windows 7 及更高版本中请务必使用 64 位版本。否则有些事情,例如调用 64 位程序的链接,将无法正常工作。
总结一下,你可以
无论哪种情况,将控制台窗口字体更改为 TrueType 字体都是一个好主意——是的,这会影响功能,而不仅仅是外观。
注意微软的其他荒谬之处:在 Windows 7 及更高版本中,默认情况下在控制台窗口中使用的“系统”字体实际上是在幕后,具有数千个字形的 TrueType 字体,但它用于模拟旧的 16 位 Windows 位图字体, 有同样愚蠢的限制,所以你仍然必须更改为其他一些 TrueType 字体......
(1)参见 C++11 标准 §2.3/3。
(2) “Windows ANSI”取决于 Windows 配置,始终是GetACP
API 函数指定的代码页。实际上,此函数从上面引用的注册表键/值中获取其值。但是,这在很大程度上是无证的。
(3)在 Windows XP 中,Windows 会询问您是否要保存单个控制台窗口配置。从 Windows Vista 开始,它会毫无疑问地保存,也没有任何信息表明它已保存。没有用于删除此类已保存配置的用户界面,但可以通过以编程方式更改快捷方式文件和/或通过注册表编辑来删除它们,但这是一种不切实际且脆弱的解决方案。