printf not flush after the call unless a newline is in the format string? Is this POSIX behavior? How might I have
printf immediately flush every time?
stdout stream is line buffered by default, so will only display what’s in the buffer after it reaches a newline (or when it’s told to). You have a few options to print immediately:
stderris unbuffered by default):
fprintf(stderr, "I will be printed immediately");
stdoutwhenever you need it to using
printf("Buffered, will be flushed"); fflush(stdout); // Will now print everything in the stdout buffer
Disable buffering on stdout by using
Or use the more flexible
setvbuf(stdout, NULL, _IONBF, 0);
No, it’s not POSIX behaviour, it’s ISO behaviour (well, it is POSIX behaviour but only insofar as they conform to ISO).
Standard output is line buffered if it can be detected to refer to an interactive device, otherwise it’s fully buffered. So there are situations where
printf won’t flush, even if it gets a newline to send out, such as:
This makes sense for efficiency since, if you’re interacting with a user, they probably want to see every line. If you’re sending the output to a file, it’s most likely that there’s not a user at the other end (though not impossible, they could be tailing the file). Now you could argue that the user wants to see every character but there are two problems with that.
The first is that it’s not very efficient. The second is that the original ANSI C mandate was to primarily codify existing behaviour, rather than invent new behaviour, and those design decisions were made long before ANSI started the process. Even ISO nowadays treads very carefully when changing existing rules in the standards.
As to how to deal with that, if you
fflush (stdout) after every output call that you want to see immediately, that will solve the problem.
Alternatively, you can use
setvbuf before operating on
stdout, to set it to unbuffered and you won’t have to worry about adding all those
fflush lines to your code:
setvbuf (stdout, NULL, _IONBF, BUFSIZ);
Just keep in mind that may affect performance quite a bit if you are sending the output to a file. Also keep in mind that support for this is implementation-defined, not guaranteed by the standard.
ISO C99 section
7.19.3/3 is the relevant bit:
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
It’s probably like that because of efficiency and because if you have multiple programs writing to a single TTY, this way you don’t get characters on a line interlaced. So if program A and B are outputting, you’ll usually get:
program A output program B output program B output program A output program B output
This stinks, but it’s better than
proprogrgraam m AB ououtputputt prproogrgram amB A ououtputtput program B output
Note that it isn’t even guaranteed to flush on a newline, so you should flush explicitly if flushing matters to you.