在同一个程序中混合cout和wcout

时间:2012-01-20 21:15:43

标签: c++

我正在阅读“C ++ Cookbook”,其中包含以下代码段:

// cout  << s  << std::endl;  // You shouldn't be able to
wcout << ws << std::endl;     // run these at the same time

如果您对查看实际示例感兴趣,请参阅a link to the page on Google books

另外,我发现这个SO question似乎表明混合wcout和cout是可以的。有人可以向我解释一下这个评论的内容吗?

修改

来自C ++标准[27.4.1]:

  

对相应的宽字符和窄字符流的混合操作遵循与在FILE上混合此类操作相同的语义,如ISO C标准的修订1中所规定。

来自C标准[7.19.2]:

  

每个流都有一个方向。在流与外部文件关联后,但是   在对其执行任何操作之前,流是没有方向的。一次广泛   字符输入/输出功能已应用于没有方向的流,该流成为面向广泛的流。类似地,一旦字节输入/输出功能具有   已经应用于没有方向的流,该流成为面向字节的流。   只有调用freopen函数或fwide函数才能改变   流的方向。 (成功调用freopen会删除任何方向。)

     

字节输入/输出功能不应用于面向广泛的流和宽的   字符输入/输出函数不应该应用于面向字节的流。

所以,标准似乎说你不应该混合它们。但是,我发现了这句话from this article

  

对于Visual C ++ 10.0,fwide函数被记录为未实现。从实际的角度来看,至少在输出整行的水平上,它显然可以很好地混合使用cout和wcout。所以,很高兴,Visual C ++显然只是忽视了标准的要求,并没有保持一个不切实际的显式C FILE流方向。

另外,关于gcc我从here找到了这句话:

  

这是(新)功能,而不是bug,请参阅libstdc ++ / 11705以及一般搜索   关于C标准中的流定向(C99,7.19.2)。简而言之,你   不能混合面向字节和面向广的I / O.目前,由于 bug   在libstdc ++ / 11705中指出,你可以获得接近你的东西   通过调用std :: ios :: sync_with_stdio(false)的期望;在。。。之初   你的计划。

5 个答案:

答案 0 :(得分:19)

首次调用coutwcout时,stdout的方向会设置。在cout的情况下,stdout变为面向字节的流,而在wcout的情况下,stdout变为面向广播的流。根据C ++标准[27.4.1]和C标准[7.19.2],一旦设置了流的方向,就不应该调用与该流的方向不兼容的函数。

答案 1 :(得分:2)

我不知道。

禁止线程,你不能“同时”运行任何两个语句。不过,您当然可以在程序的不同位置使用coutwcout。它们都映射到STDOUT,那就是......虽然你可能会因为不同的缓冲区而犯规,并且在某些情况下会略微出现意外排序。

显然,每个人都在“目标”流STDOUT上嵌入方向,并且不允许在已充满方向{{1}的流上混合操作}和[C++11: 27.4.1]

答案 2 :(得分:1)

从技术上讲,您绝对可以同时使用窄流和宽流。但是,除非您安排两个字符编码相同的字符,否则结果可能会混乱。遗憾的是,这一点需要注意的是,您无法控制标准流对象使用的编码,至少不能移植。即使编码相同,也需要确保完全写入部分字符,即至少在切换到另一个宽度时需要刷新缓冲区。

答案 3 :(得分:1)

违反“不得”的标准通常会使你陷入未定义的行为领域。未定义的行为可能在某些实现上正常工作。

答案 4 :(得分:0)

猜测:coutwcout是两个不同的流,您提供的引号没有说明流方向如何与底层文件的方向相关联。可能是这些流在引擎盖下默默地重新定位stdout