显示扩展ASCII字符

10

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

例如:

cout << "¿" << endl;  //inverted question mark

输出:

┐
Press any key to continue . . .

看起来工作得很好,只是你的字符集不匹配。欢迎来到遗留字符集的世界,因为似乎 Windows 控制台仍然(!!)不支持 Unicode。 - Matti Virkkunen
3
Windows控制台支持Unicode编码,确切地说是“WriteConsoleW”函数支持Unicode编码,“WriteConsoleA”函数显然不支持。 - MSalters
5个回答

13
Windows的控制台窗口是纯Unicode的。它的缓冲区将文本存储为UCS-2 Unicode(每个字符16位,类似于现代21位Unicode的基本多语言平面限制)。因此,控制台窗口可以显示几乎所有类型的文本。但是,对于每个字符一个字节的(以及可能也适用于一些可变长度编码),Windows会自动将其翻译成/从控制台窗口的活动代码页。如果控制台窗口是[cmd.exe]实例,则可以通过命令“chcp”(缩写为“change codepage”)检查它。代表默认代码页的OEM意味着“控制台窗口的默认代码页”,其中代码页437只是原始代码页:例如,可以通过“chcp”在每个窗口上配置它。在Windows中,控制台窗口使用OEM作为非Unicode的代码页。而记事本、其他编辑器等则使用ANSI。因此,在Windows中,C ++源代码通常使用ANSI进行编码,而控制台窗口则假定使用OEM。
cout << "I like Norwegian blåbærsyltetøy!" << endl;

可以使用基于Unicode的控制台窗口API直接向控制台窗口输出Unicode以避免转换,但这很麻烦。请注意,使用wcout而不是cout并没有帮助:按设计wcout仅从宽字符字符串向程序的窄字符集进行转换,并在此过程中丢失信息。可能很难相信,C++标准库提供了一大块非常复杂的功能是无意义的(因为这些转换本可以由cout支持),但事实就是如此。也许这是某种政治妥协,但无论如何,wcout都没有帮助,即使它在某种程度上有意义,那么逻辑上它应该帮助解决这个问题。

那么一个挪威的初学者程序员怎么样才能呈现出“blåbærsyltetøy”呢?

很简单,只需将活动代码页更改为ANSI即可。由于在大多数西方国家的PC上,ANSI是代码页1252,因此您可以通过以下方式为给定的命令解释器实例执行此操作:

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

现在,像[edit.com]这样的旧DOS程序将产生一些无用的东西,因为ANSI中没有原始PC字符集线绘制字符,而且由于国家字符在ANSI中具有不同的代码。但是,谁使用旧的DOS程序呢?不是我!

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

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage

在此键中,将OEMCP的值更改为1252,并重新启动。

chcp或其他更改为代码页1252的操作一样,会导致旧的DOS程序呈现无用的东西,但使C++程序或其他现代控制台程序正常工作。

由于在控制台窗口和Windows的其他部分中都使用相同的字符编码。


4

当你打印一个ASCII字符串时,Windows会根据当前的代码页将其内部转换为UNICODE。CRT还会进行从UNICODE到“ASCII”的转换。以下内容可以正常工作。

#include <fcntl.h>
#include <io.h>
#include <stdio.h>
#include <iostream>

void
__cdecl
main(int ac, char **av)
{
    _setmode(_fileno(stdout), _O_U16TEXT);
    std::wcout  << L"\u00BF";
}

2
由于Win32控制台使用代码页437(也称为OEM字体)来呈现字符,而Windows的大多数其他部分使用Windows-1252进行单字节字符编码。
字符“¿”是Unicode字符INVERTED QUESTION MARK,其在Unicode、ISO 8859-1和Windows-1252中的代码点为0xBF(191十进制)。CP437中的代码点0xBF对应于字符“┐”,它是BOX DRAWINGS LIGHT DOWN AND LEFT(代码点U+2510)。
只要您正在使用Windows控制台,就只能显示CP437中的字符,而不能显示其他字符。如果要显示其他Unicode字符,则需要使用不同的环境。

1

我正在使用Win10 b19043操作系统。 切换到Unicode代码页(65001)可以在CMD窗口中打印/显示扩展ASCII字符。只需在您的控制台或批处理文件中输入此行,一切都应该正常:

chcp 65001 1>nul

CMD with Unicode codepage


0

它可能是使用基本的ASCII字符集实现的。在创建控制台时,微软程序员没有添加UTF-8功能。这只是一个猜测,因为我不是参与创建控制台的微软程序员。


3
你可以将UTF-8推送到Windows控制台。 - David Heffernan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接