问题
I know there are many buffer questions on here but I can't seem find a clear answer on this.
std::cout << "write to screen" << std::endl;
I know this code will write to the screen and flush the buffer because of the "endl", but if I wrote this:
std::cout << "write to screen";
Wouldn't the buffer be flushed regardless since the text has been outputted to the screen?
回答1:
Wouldn't the buffer be flushed regardless since the text has been outputted to the screen?
Assuming that you have seen the text outputted to the screen, then yes, the buffer has been flushed.
I believe the confusion is regarding this line:
std::cout << "write to screen";
The absence of std::endl
doesn't mean "don't flush the buffer". It simply means "I'm not saying when to flush the buffer".
回答2:
There are multiple ways to ensure your std::ostream
is flushed:
- Manually with std::endl, std::flush, or a direct call to ostream::flush().
- Depending on a later used input stream being bound to your ostream: std::basic_ios::tie().
Depending on the tie to C streams: std::ios_base::sync_with_stdio
This means that anything which would flush the corresponding C stream will also flush the C++ stream, like a call to
fflush()
, or the (maybe automatically) selected buffering strategy.
Like line-buffering.From C11 draft:
7.21.3 Files
3 When a stream is unbuffered, characters are intended to appear from the source or at the destination as soon as possible. Otherwise characters may be accumulated and transmitted to or from the host environment as a block. When a stream is fully buffered, characters are intended to be transmitted to or from the host environment as a block when a buffer is filled. When a stream is line buffered, characters are intended to be transmitted to or from the host environment as a block when a new-line character is encountered. Furthermore, characters are intended to be transmitted as a block to the host environment when a buffer is filled, when input is requested on an unbuffered stream, or when input is requested on a line buffered stream that requires the transmission of characters from the host environment. Support for these characteristics is implementation-defined, and may be affected via the setbuf and setvbuf functions.
7 At program startup, three text streams are predefined and need not be opened explicitly — standard input (for reading conventional input), standard output (for writing conventional output), and standard error (for writing diagnostic output). As initially opened, the standard error stream is not fully buffered; the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device.- Waiting on the internal buffer overflowing.
Now, as a general guideline: Don't manually flush your streams, doing so can significantly degrade performance. Unless, of course, it's neccessary for correctness.
回答3:
std::cout << "Hello" << std::endl;
will write to the screen before executing the next line of code, while
std::cout << "Hello\n";
will print the same, but some time before your program exits normally or you use std::cin
(or another instream you tie to std::cout
by hand). That means that if your program is terminated abruptly or hangs in an infinite loop, you might not see the output at all.
回答4:
"Wouldn't the buffer be flushed regardless since the text has been outputted to the screen?"
No! std::endl
implies flushing. The underlying buffer won't be flushing (written on the screen),
until hitting a certain watermark (buffer size).
If you want to have it flushed, call cout.flush()
explicitely:
std::cout << "write to screen";
std::cout.flush();
The real key to the solution is, what the underlying std::basic_streambuf interface actually implements.
There could be various implementations:
- Calling
flush()
every time the certain watermark of the underlying buffer is hit - Calling
flush()
every time (not very efficient) - Calling
flush()
as soon a'\n'
had been printed - Calling
flush()
as guaranteed withstd::endl
The internal buffer management shouldn't be your business of concern, unless you're trying to provide your own std::basic_streambuf
implementation.
来源:https://stackoverflow.com/questions/27910422/c-flushing-the-buffer