一个困扰我的谜题。在一些简单的测试工具代码中,如果我将太多字符流式传输到stdout,程序将失败。奇怪但非常可重复。这可能是Windows唯一的问题,但很容易看到:
#include <iostream>
#include <deque>
using namespace std;
int main()
{
deque<char> d;
char c;
while (cin.get(c)) d.push_back(c);
for (deque<char>::reverse_iterator j = d.rbegin(); j != d.rend(); j++)
cout << (*j);
}
前面的代码只是从stdin加载一个chars流并以相反的顺序输出它们。它适用于最多100K左右的字符,但在Windows中出现“错误写入stdout”消息,因为文件较大。它总是以相同的角色而死。 像“cat bigfile.txt | reverse.exe”这样的shell命令是重现问题所需要的。 MSFT和英特尔编译器的行为都相似。
我意识到stdout上可能有一个缓冲区,但是当它被填满时不应该自动刷新?
答案 0 :(得分:4)
您可以尝试强制缓冲区以这种方式刷新其内容:
cout << (*j) << std::flush;
否则std::endl
也有效,但也提供和行尾(你不想让我猜想?)
答案 1 :(得分:1)
这里没有这样的问题:
C:\Temp> cl
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
编辑:更多信息
我通过编译您发布的程序对此进行了测试。我创建了一个由0123456789组成的文件,重复100,000次(使其大小为1,000,000字节)。然后,我跑了
C:\Temp> t.exe < test.in
以及
C:\Temp> cat test.in | t.exe
和
C:\Temp> t.exe < test.in > test.out
没有问题。虽然等待1,000,000个字符滚动确实需要一段时间。
答案 2 :(得分:1)
问题可能是管道操作员(|)而不是“猫”。 Windows命令解释器[1]没有真正的管道(如Unix)并使用临时文件模拟它们。您可能正在耗尽磁盘空间或在命令解释程序中溢出某些缓冲区。
您可以尝试“输入bigfile.txt | reverse.exe”,看看是否得到相同的结果。
[1]至少旧版本没有真正的管道。我没有看过最新版本。有趣的是,Michael Burr无法在Vista x64上重现它。也许MS已经解决了这个问题。
答案 3 :(得分:0)
在每次循环迭代期间,或者每100次迭代,您可以在短时间内睡眠吗?这将使操作系统有机会刷新缓冲区。
我不知道在c ++中执行此操作的命令是什么,但在c#中它是
System.Threading.Sleep(10);
答案 4 :(得分:0)
感谢所有的建议,特别是Michael Burr,他正确地认为cat命令,而不是reverse.exe,可能会失败!这正是它的原因.. reverse.exe&lt; bigfile.txt工作正常,但cat bigfile.txt | reverse.exe失败并显示“写入标准输出错误”。 现在为什么CAT会失败也是一个谜,但至少它现在不是代码相关的东西。
答案 5 :(得分:0)
如果您尝试在win32上向stdout写一个特殊字符,我之前就遇到过这个问题。您的测试数据中有任何此类字符吗?