wcout是如何工作的?

3

在控制台应用程序中使用wcout时,我注意到了一个奇怪的问题。

调用某个函数后,其余的wcout调用完全不起作用。即输出语句没有出现在控制台上。

我注意到,在该函数中,我使用了一个从未赋值的宽字符数组。

WCHAR wArray[1024];
wcout<<wArray<<endl;

在这个电话之后,所有其他的wcout都停止工作了。

因此,我很好奇wcout与cout有何不同,以及为什么会出现这个问题。

2个回答

5

wcout 可能会对输出进行一些 Unicode 验证,并在验证失败时使输出失败。这部分原因是 Windows 控制台子系统处理 Unicode 不太好。

检查流是否设置了 failbitbadbit。重置流(例如,wcout.clear())应该可以恢复流的功能。

严格来说,cout 是一个 std::basic_ostream<char>,而 wcout 是一个 std::basic_ostream<wchar_t>…… 这实际上就是它们之间的差异。只是如果要形成良好的 Unicode,需要满足更多的要求。


4

这个例子会导致未定义的行为。

operator<<(std::wostream&,const wchar_t*) 期望缓冲区以空字符结尾,并在遇到第一个L'\0'字符时停止打印字符。 如果缓冲区恰好包含空字符(L'\0'),则代码将“正确”运行(尽管输出是不可预测的)。 如果没有,则operator<<将继续读取内存,直到遇到一个空字符。

你的示例没有强制使用空终止符。 相比之下,以下内容将打印出未指定数量的字符,很可能是垃圾,但是是明确定义的:

WCHAR wArray[1024];
wArray[1023] = L'\0';
wcout << wArray << endl;

注意:仅仅因为数组没有被赋值,不意味着该数组无效。例如,有人可能对它进行了wcscpy操作。我假设声明只是为了在我的答案中显示变量类型。如果OP确实只是传递了未初始化的数组,则这是正确的答案。否则,我认为我的答案是正确的。+1。 - Billy ONeal
1
@Billy:我将“never assigned to”解释为“未初始化”。确实,如果数组是“有效的”,那么.clear()应该重置流状态。 - André Caron
谢谢你们两位的帮助。但是,我认为情况就是这样。当我使用调试器悬停在 wArray 上时,它显示了一连串没有结束的垃圾字符。 - roymustang86

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