1. Problem It Solves
Writing another line does not always require sending the buffer immediately. \n inserts a newline; std::endl inserts a newline and flushes; std::flush only flushes. Choose based on when the reader or receiver needs the data.
2. Prerequisites
std::cout,<<, and strings.A buffer temporarily holds data before passing it to a lower I/O layer.
3. Core Idea
Flushing asks the stream to synchronize its buffer with the destination below it. This can be costly, so forcing a flush after every line can slow bulk output. A flush does not itself guarantee durable disk storage.
'\n' does not request a flush, but one may happen for other reasons, such as unitbuf, stream ties, or lower-layer I/O behavior. See the definitions of endl and flush.
4. Minimal Syntax
output << "one line\n";
output << "prompt: " << std::flush;
output << "done" << std::endl;These are three separate choices for an already-declared output stream: a normal line, an immediately flushed prompt, or a newline followed by a flush.
5. How It Works
Identify when data needs to be sent immediately. Bulk file output commonly uses
\n; an interactive prompt may need flushing before waiting for a reply.Check stream ties. By default,
std::cinis tied tostd::cout, so input operations normally flush output first. Afterstd::cin.tie(nullptr), you must arrange prompt flushing when needed.std::ios::sync_with_stdio(false)changes coordination between standard C++ streams and C stdio; it is not a flush operation. Once disabled, do not rely on interleavedprintfandcoutordering as with synchronized streams. Calling it after I/O has occurred has implementation-defined effects.Check formatting state:
fixed,scientific, base, precision, and fill generally persist until changed.std::setwsets width, which is commonly consumed by the next applicable insertion.A helper using a shared stream should save and restore the properties it changes, including on exceptions. After an important write or flush, inspect the stream's error state rather than treating the call as proof of success.
6. Common Mistakes
Replacing every
\nwithstd::endland expecting identical cost.Removing a tie but forgetting to flush a prompt without a newline.
Setting
std::fixedin a helper and accidentally changing later output.Assuming
std::setprecision(2)always means two decimal places; withfixedit does, while default formatting uses significant digits.Assuming a flush guarantees durable storage or cannot fail.
7. When to Use It
Use \n for ordinary lines and flush at interaction or protocol boundaries that require data to be sent immediately. To prepare independently formatted text without changing a shared stream, build it in a std::ostringstream first.
8. Simple Example
The C++20 sample keeps formatting on a separate stream:
std::ostringstream output;
output << std::fixed << std::setprecision(2);
output << 3.14159 << '\n' << 2.0;With <sstream> and <iomanip>, the resulting string is 3.14\n2.00. 2.0 still has two decimal places because formatting has not changed. The sample then writes the string to cout and flushes once at the end.
Complete sample code
Source file
dailycppinterview/258_output-stream-buffering-and-state/main.cpp
// Real-World C++ Interviews Q258: How do C++ output buffering, '\n', std::endl, std::flush,
// stream ties, and persistent formatting state affect correctness and performance?
// Key: Writing '\n' inserts a newline without requiring a flush. std::endl inserts a newline
// and then flushes, while std::flush flushes without adding a character. Repeated forced
// flushing can dominate otherwise cheap output, so use it for an interactive or protocol
// boundary that needs visibility rather than after every line. A tied input stream may flush
// its output stream before reading, and sync_with_stdio controls coordination with C stdio
// rather than merely making output faster. Formatting such as fixed, scientific, base, fill,
// and precision generally remains on that stream until changed; width is commonly a one-use
// setting. Save and restore shared-stream state when a helper must not affect later callers. A
// flush asks buffered layers to pass data onward but does not by itself guarantee durable
// storage.
#include <iomanip>
#include <iostream>
#include <sstream>
int main() {
std::ostringstream output;
output << std::fixed << std::setprecision(2);
output << 3.14159 << '\n' << 2.0;
std::cout << output.str() << '\n';
std::cout.flush();
}
9. Key Takeaways
Distinguish inserting characters, flushing buffers, and changing formatting. Each has its own purpose and state; check errors when output success matters.
10. Self-Check Question
Full question: How do C++ output buffering, '\n', std::endl, std::flush, stream ties, and persistent formatting state affect correctness and performance?
Why does the example print 2.00 instead of 2? After cin.tie(nullptr), how do you show a prompt before input begins? Does flushing guarantee durable disk storage?