考虑以下代码片段,在 MS Visual Studio 2010/2012 上编译为控制台应用程序并在 Win7 上执行:
#include "stdafx.h"
#include <iostream>
#include <string>
const std::wstring test = L"hello\xf021test!";
int _tmain(int argc, _TCHAR* argv[])
{
std::wcout << test << std::endl;
std::wcout << L"This doesn't print either" << std::endl;
return 0;
}
第一个 wcout 语句输出“hello”(而不是类似“hello?test!”的内容) 第二个 wcout 语句不输出任何内容。
就好像 0xf021(和其他?)Unicode 字符导致 wcout 失败。
这个特殊的 Unicode 字符 0xf021(编码为 UTF-16)是基本多语言平面中“私有(private)使用区域”的一部分。我注意到 Windows 控制台应用程序没有对 Unicode 字符的广泛支持,但通常每个字符至少由默认字符(例如“?”)表示,即使不支持渲染特定字形。
是什么导致 wcout 流阻塞?进入这个状态后有办法重置吗?
最佳答案
wcout
,或者准确地说,它内部使用的 wfilebuf
实例,将宽字符转换为窄字符,然后将它们写入文件(在您的情况下, 标准输出
)。转换由流区域设置中的 codecvt
方面执行;默认情况下,这只是 wctomb_s
,转换为系统默认的 ANSI 代码页,又名 CP_ACP
。
显然,字符 '\xf021'
在系统上配置的默认代码页中无法表示。因此转换失败,并且在流中设置了failbit
。一旦设置了failbit
,所有后续调用都会立即失败。
我不知道有什么方法可以让 wcout
成功地将任意 Unicode 字符打印到控制台。 wprintf
可以工作,但需要进行一些调整:
#include <fcntl.h>
#include <io.h>
#include <string>
const std::wstring test = L"hello\xf021test!";
int _tmain(int argc, _TCHAR* argv[])
{
_setmode(_fileno(stdout), _O_U16TEXT);
wprintf(test.c_str());
return 0;
}
关于visual-c++ - 为什么某些 Unicode 字符会导致 std::wcout 在控制台应用程序中失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19193429/