Limit cout stream?

The puzzle that hit me. In some simple wiring code, if I pass too many characters to stdout, the program fails. Strange, but very reproducible. This may be a problem only with Windows, but it is easy to see:

#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); } 

The previous code just loads the stream of characters from stdin and prints them in reverse order. It works fine up to 100K or so characters, but dies with the "stdout" error message on Windows for files that are larger. He always dies with the same character. A shell like "cat bigfile.txt | reverse.exe" is all you need to reproduce the problem. Both MSFT and Intel compilers operate in a similar fashion.

I understand that there may be a buffer on stdout, but should it not be automatically flushed when it is full?

+4
source share
6 answers

Thanks for all the suggestions, especially to Michael Barr, who correctly suggested that the cat command, and not reverse.exe, could be unsuccessful! This is exactly what it was .. reverse.exe <bigfile.txt works fine, but cat bigfile.txt | reverse.exe fails with a "stdout write error". Now why CAT will fail is also a mystery, but at least now it is not something related to the code.

0
source

You can try to get the buffer to flush your content this way:

 cout << (*j) << std::flush; 

Otherwise, std::endl also works, but it also provides the end of the line (which you don't want, I suppose?)

+4
source

There is no such problem here:

 C:\Temp> cl Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86 

EDIT: Additional Information

I tested this by compiling the program you published. I created a file consisting of 0123456789, repeating 100,000 times (whose size is 1,000,000 bytes). Then i ran

 C:\Temp> t.exe < test.in 

and

 C:\Temp> cat test.in | t.exe 

and

 C:\Temp> t.exe < test.in > test.out 

There were no problems. It took quite a while to wait for 1,000,000 characters to pass through.

+1
source

The problem is likely to be the pipe operator (|), not the "cat". The Windows command interpreter [1] has no real channels (for example, Unix) and imitates them using temporary files. You may have low disk space or some buffer overflow in the command interpreter.

You can try "type bigfile.txt | reverse.exe" and see if you get the same results.

[1] At least the older versions did not have real pipes. I did not watch the latest versions. Interestingly, Michael Burr was unable to play it on Vista x64. Maybe MS fixed the problem.

+1
source

Can you sleep for a short period of time during each iteration of the loop, or perhaps every 100 iterations? This will enable the OS to flush the buffer.

I don’t know which command to do this in C ++, but in C # it

 System.Threading.Sleep(10); 
0
source

I had this problem before occurring if you tried to write a special character for stdout on win32. Any such characters in your test data?

0
source

All Articles