在 Windows C++ 中更改控制台代码页

Fra*_*cis 1 c++ windows unicode windows-xp utf-8

我正在尝试在 Windows 命令行中输出 UTF8 字符。我似乎无法让该功能setConsoleOutputCP正常工作。我还听说你必须更改字体才能"Lucida Grande"使其正常工作,但我也无法使其正常工作。有人可以为我提供一个简短的示例,说明如何使用这些函数将 UTF-8 字符正确输出到控制台吗?

另外我听说这些功能在 Windows XP 中不起作用,是否有更好的替代方法来替代那些在 Windows XP 中起作用的功能?

Adr*_*thy 6

[我知道这个问题很旧,并且与 Windows XP 相关,但它似乎仍然是放置此信息的好地方,以便我(也许还有其他人)将来可以再次找到它。]

\n\n

在较新版本的 Windows 中,CMD Windows 中对 Unicode 的支持得到了改进。该程序将在 Windows 10 上运行。

\n\n
#include <iostream>\n#include <Windows.h>\n\nclass UTF8CodePage {\n  public:\n    UTF8CodePage() : m_old_code_page(::GetConsoleOutputCP()) {\n      ::SetConsoleOutputCP(CP_UTF8);\n    }\n    ~UTF8CodePage() { ::SetConsoleOutputCP(m_old_code_page); }\n\n  private:\n    UINT m_old_code_page;\n};\n\nint main() {\n  UTF8CodePage use_utf8;\n  const char *text = u8"This text is in UTF-8. \xc2\xa1Ol\xc3\xa9! \xe4\xbd\xbb\\n";\n  std::cout << text;\n  return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我创建了一个 RAII 类来确保恢复代码页,因为如果用户故意选择了特定的代码页,则保留更改的代码页是不礼貌的。所有特定于 Windows 的代码 ( SetConsoleOutputCP ) 都包含在该类中。use_utf8中变量的定义main将代码页更改为 UTF-8,并且该代码页将保持有效,直到该变量在作用域末尾被破坏。

\n\n

请注意,我u8在字符串文字上使用了前缀,这是 C++ 的一项较新功能,用于确保字符串使用 UTF-8 进行编码,而不管源文件使用的编码如何。如果您有其他方法来生成有效的 UTF-8 文本字符串,则不必使用该功能。

\n\n

您仍然必须确保 CMD 窗口使用的字体支持您需要的字形。我认为没有办法自动获取字体链接。\n 但如果字体缺少字形,这至少会显示替换字符。例如,在我的窗口上,\xc2\xa1Ol\xc3\xa9!看起来正确,但 CJK 字形显示大约类似于\xef\xbf\xbd。如果用户复制该替换字符,剪贴板将收到原始字形,因此他们可以将其粘贴到其他程序中而不会损失任何保真度。

\n\n

main请注意,从\'s获取的命令行参数argv将位于原始代码页中。解决此问题的一种方法是使用GetCommandLineW获取未转换的“宽”命令行,使用WideToMultibyte将其转换为 UTF-8 ,然后自行解析。或者,您可以将 GetCommandLineW 的结果传递给CommandLineToArgvW,后者将对其进行解析,然后将每个参数转换为 UTF-8。

\n\n

最后,请注意,更改代码页仅影响输出。如果您输入用户的文本,则该文本会使用原始代码页(通常称为 OEM 代码页)进行编码。

\n\n

TODO:找出输入。 SetConsoleCP没有做我认为文档所说的应该做的事情。

\n