Categories
c flush printf

Why does printf not flush after the call unless a newline is in the format string?

647

Why does 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?

5

  • 2

    did you investigated whether this happens with any file or only with terminals? that would sound to be a clever terminal feature not to output uncompleted line from a background program, though i expect it wouldn’t apply to the foreground program.

    – PypeBros

    Nov 12, 2009 at 16:50

  • 8

    Under Cygwin bash I’m seeing this same misbehaviour even if a newline is in the format string. This problem is new to Windows 7; the same source code worked fine on Windows XP. MS cmd.exe flushes as expected. The fix setvbuf(stdout, (char*)NULL, _IONBF, 0) works around the problem, but surely should not have been necessary. I’m using MSVC++ 2008 Express. ~~~

    Jan 8, 2013 at 14:10

  • 12

    To clarify the title of the question: printf(..) does not do any flushing itself, it’s the buffering of stdout that may flush when seeing a newline (if it’s line-buffered). It would react the same way to putchar('\n');, so printf(..) is not special in this regard. This is in contrast with cout << endl;, the documentation of which prominently mentions flushing. The documentation of printf doesn’t mention flushing at all.

    Apr 5, 2016 at 14:02


  • 2

    writing (/flushing) is potentially an expensive operation, it’s probably buffered for performance reasons.

    Aug 17, 2017 at 23:31


  • @EvgeniSergeev: Is there a consensus that the question has incorrectly diagnosed the problem, and that flushing happens when there is a newline in the output? (putting one in the format string is one way, but not the only way, of getting one in the output).

    – Ben Voigt

    May 1, 2020 at 17:54


838

The 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:

  • Print to stderrinstead using fprintf (stderr is unbuffered by default):

    fprintf(stderr, "I will be printed immediately");
    
  • Flush stdout whenever you need it to using fflush:

    printf("Buffered, will be flushed");
    fflush(stdout); // Will now print everything in the stdout buffer
    
  • Disable buffering on stdout by using setbuf:

    setbuf(stdout, NULL);
    
  • Or use the more flexible setvbuf:

    setvbuf(stdout, NULL, _IONBF, 0); 
    

15

  • 287

    Or, to disable buffering entirely: setbuf(stdout, NULL);

    – Andy Ross

    Nov 11, 2009 at 17:42

  • 99

    Also, just wanted to mention that apparently in UNIX a newline will typically only flush the buffer if stdout is a terminal. If the output is being redirected to a file, a newline won’t flush.

    – hora

    Mar 5, 2011 at 23:10

  • 7

    I feel that I should add: I’ve just been testing this theory, and I am finding that using setlinebuf() on a stream which is not directed to a terminal is flushing at the end of each line.

    – Doddy

    Sep 6, 2011 at 19:06

  • 8

    “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” — see this question: stackoverflow.com/questions/5229096/…

    May 22, 2015 at 7:23

  • 3

    @RuddZwolinski If this is going to be a good canon answer of “why isn’t it printing” it seems important to mention the terminal/file distinction as per “Does printf always flush the buffer on encountering a newline?” directly in this highly upvoted answer, vs people needing to read the comments…

    Apr 8, 2016 at 22:08

140

+100

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:

myprog >myfile.txt

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 setbuf and setvbuf functions.

3

  • 9

    I just came across a scenario where even there is a ‘\n’, printf() doesn’t flush. It was overcome by adding a fflush(stdout), as you mentioned here. But I am wondering the reason why ‘\n’ failed to flush the buffer in printf().

    – Qiang Xu

    Apr 28, 2012 at 19:45

  • 11

    @QiangXu, standard output is line buffered only in the case where it can be definitively determined to refer to an interactive device. So, for example, if you redirect output with myprog >/tmp/tmpfile, that is fully buffered rather than line buffered. From memory, the determination as to whether your standard output is interactive is left to the implementation.

    – paxdiablo

    Apr 29, 2012 at 0:20


  • 4

    furthermore on Windows calling setvbuf(…., _IOLBF) will not work as _IOLBF is the same as _IOFBF there: msdn.microsoft.com/en-us/library/86cebhfs.aspx

    Feb 5, 2015 at 10:02

33

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.

1

  • Funny, I think this is the only answer which actually answers the “why?” – applying an appropriate amount of guessing. The others explain that it is buffered (which does seem less necessary towards an OP who demonstrates awareness of that by using the term “flushing”) and how to avoid/control it. Admittedly there is enough detail there to provide helpful insights in answers. But only this one discusses why and has that angle of answering all to itself. Cheers.

    – Yunnosch

    Feb 5 at 7:58