2011-04-21 37 views
0

我试图在windows命令提示符下输出以下字符:ュ(U + FF6D)。wcout不会写宽字符到命令提示符

我能够看到使用WriteConsoleW写出字符。我也能够看到字符,如果我使用WideCharToMultiByte使用CP_ACP代码页(chcp返回932:日语)。但是,当我尝试在WriteConsoleW成功打印的相同字符串上使用常规wcout时,它会窒息。

当我执行setlocale(LC_ALL,“”)时,它会打印English_UnitedStates.1252(我安装时的默认代码页)。

为什么wcout在其他人成功时失败?

注:我重新启动机器的系统区域设置更改为日本

+2

你曾经调用'std :: wcout.imbue()'来改变'wcout'的代码页吗? – ildjarn 2011-04-21 23:30:16

+0

工作。但是,当我重置系统区域设置时,为什么wcout的代码页不同?发表一个解释,你会得到简单的点。 – bogertron 2011-04-21 23:34:59

回答

2

C++ iostreams的默认语言环境始终是“C”语言环境。从C++ 03标准,§27.4.2.3/ 4:

locale getloc() const;

如果没有语言环境已经充满,在施工时间的全局C的副本++语言环境,locale(),实际上。

从§22.1.1.2/ 1-2:

locale() throw();

默认构造方法:目前全球区域的快照。

构造最后传递给locale::global(locale&)的参数的副本,如果它已被调用;否则,生成的构面具有与locale::classic()相同的虚函数语义。

从§22.1.1.5/ 4-6:

static const locale& classic();

的 “C” 语言环境。

返回:实现经典“C”语言环境语义的语言环境,等效于值locale("C")

注意:此语言环境,其构面及其成员函数不随时间而改变。

作为std::coutstd::wcout具有静态存储持续时间,它们保证main之前被初始化被调用,并且因此将总是具有在应用程序启动的“C”语言环境;即在执行时没有足够的时间点,可以调用locale::global并更改std::coutstd::wcout的默认语言环境。因此,如果您想使用非默认代码页,则必须始终自己填充全局流。

+0

所以我想这是一个特定于Windows的问题。在我的应用程序中,我没有在任何时候调用cout.imbue,但它仍然可以处理代码页字符。我是在假设(是假设邪恶的东西),wcout会灌输相同的语言环境。 – bogertron 2011-04-22 00:02:43

0

wcout创建之前的任何代码main执行。当您拨打setlocale时,wcout已经在那里,准备好做它的事情。它不会尝试跟踪随后可能对setlocale所做的更改,因此它将继续使用默认值,而不是您使用setlocale设置的值。

+0

好的,这是有道理的,但如果我的机器启动了一个能够打印字符(U + FF6D)的语言环境,它具有映射字符到CP 932.我想我的问题是如何定义wcout的默认语言环境? – bogertron 2011-04-21 23:52:31

+0

@bogertron:我的回答解决了这方面的问题。 – ildjarn 2011-04-21 23:54:34