18

stdout is line-buffered when connected to a terminal, but I remember reading somewhere that reading (at least from stdin) will automatically flush stdout. All C implementations that I have used have done this, but I can't find it in the standard now.

It does make sense that it works that way, otherwise code like this:

printf("Type some input: ");
fgets(line, sizeof line, stdin);

would need an extra fflush(stdout);

So is stdout guaranteed to be flushed here?

EDIT:

As several replies have said, there seems to be no guarantee in the standard that the output to stdout in my example will appear before the read from stdin, but on the other hand, this intent is stated in (my free draft copy of) the standard:

The input and output dynamics of interactive devices shall take place as specified in 7.19.3. The intent of these requirements is that unbuffered or line-buffered output appear as soon as possible, to ensure that prompting messages actually appear prior to a program waiting for input.

(ISO/IEC 9899:TC2 Committee Draft -- May 6, 2005, page 14).

So it seems that there is no guarantee, but it will probably work in most implementations anyway. (Famous last words...)

Ry-
  • 218,210
  • 55
  • 464
  • 476
Thomas Padron-McCarthy
  • 27,232
  • 8
  • 51
  • 75
  • 1
    Following the cross reference to 7.19.3 (7.21.3 in C11) is also useful, since it mentions what input operations are expected to cause flushing. These are discussed at https://stackoverflow.com/a/39536803/8586227. – Davis Herring Oct 17 '17 at 07:02
  • The answer is Yes when talking about the glibc implementation – Steve Lau Sep 13 '22 at 06:40

6 Answers6

5

No, it does not.

ironfroggy
  • 7,991
  • 7
  • 33
  • 44
5

To answer your question, you do need the extra fflush(stdout); after your printf() call to make sure the prompt appears before your program tries to read input. Reading from stdin doesn't fflush(stdout); for you.

Alok Singhal
  • 93,253
  • 21
  • 125
  • 158
4

No. You need to fflush(stdout); Many implementations will flush at every newline of they are sending output to a terminal.

Richard Pennington
  • 19,673
  • 4
  • 43
  • 72
4

No. stdin/stdout are buffered. You need to explicity fflush(stdout) in order for the buffered data in the video memory/unix terminal's memory to be pushed out on to a view device such as a terminal. The buffering of the data can be set by calling setvbuf.

Edit: Thanks Jonathan, to answer the question, reading from stdin does not flush stdout. I may have gone off a tangent here by specifying the code demonstrating how to use setvbuf.

  #include 

  int main(void)
  {
     FILE *input, *output;
     char bufr[512];

     input = fopen("file.in", "r+b");
     output = fopen("file.out", "w");

     /* set up input stream for minimal disk access,
        using our own character buffer */
     if (setvbuf(input, bufr, _IOFBF, 512) != 0)
        printf("failed to set up buffer for input file\n");
     else
        printf("buffer set up for input file\n");

     /* set up output stream for line buffering using space that
        will be obtained through an indirect call to malloc */
     if (setvbuf(output, NULL, _IOLBF, 132) != 0)
        printf("failed to set up buffer for output file\n");
     else
        printf("buffer set up for output file\n");

     /* perform file I/O here */

     /* close files */
     fclose(input);
     fclose(output);
     return 0;
  }

Hope this helps, Best regards, Tom.

t0mm13b
  • 34,087
  • 8
  • 78
  • 110
  • How does your code relate to the behaviour of stdin and stdout? – Jonathan Leffler Jan 23 '10 at 16:44
  • @Jonathan: It is a sample of how to set the buffer for input by using setvbuf to be 512, or any figure for that matter, preferably on a word boundary. That was a sample taken from the help file on Borland C compiler showing the usage of setvbuf. – t0mm13b Jan 23 '10 at 16:50
  • 1
    The code is fine as an answer to another question - it does not address the question asked, which is "does reading from stdin flush stdout". I'm not going to penalize you for a tangential answer - but I do consider your answer tangential. – Jonathan Leffler Jan 23 '10 at 17:05
2

No, that's not part of the standard. It's certainly possible that you've used a library implementation where the behavior you described did happen, but that's a non-standard extension that you shouldn't rely on.

Michael Kohne
  • 11,888
  • 3
  • 47
  • 79
1

No. Watch out for inter-process deadlocks when dealing with std streams when either read on stdin or write on stdout blocks.

abc
  • 1,352
  • 1
  • 9
  • 13