Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
241 views
in Technique[技术] by (71.8m points)

c - What is it with printf() sending output to buffer?

I am going through "C PRIMER PLUS" and there is this topic about "OUTPUT FLUSHING". Now it says:

printf() statements sends output to an intermediate storage called buffer. Every now and then, the material in the buffer is sent to the screen. The standard C rules for when output is sent from the buffer to the screen are clear:

  1. It is sent when the buffer gets full.
  2. When a newline character is encountered.
  3. When there is impending input.

(Sending the output from the buffer to the screen or file is called flushing the buffer.)

Now, To verify the above statements. I wrote this simple program :

#include<stdio.h>

int main(int argc, char** argv) {

printf("Hello World");

return 0;
}

so, neither the printf() contains a new line, nor it has some impending input(for e.g. a scanf() statement or any other input statement). Then why does it print the contents on the output screen.

Let's suppose first condition validated to true. The buffer got full(Which can't happen at all). Keeping that in mind, I truncated the statement inside printf() to

printf("Hi");

Still it prints the statement on the console.

So whats the deal here, All of the above conditions are false but still I'm getting the output on screen. Can you elaborate please. It appears I'm making a mistake in understanding the concept. Any help is highly appreciated.

EDIT: As suggested by a very useful comment, that maybe the execution of exit() function after the end of program is causing all the buffers to flush, resulting in the output on the console. But then if we hold the screen before the execution of exit(). Like this,

#include<stdio.h>

int main(int argc, char** argv) {

printf("Hello World!");
getchar();

return 0;
}

It still outputs on the console.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Part of the specification for exit() in the C standard (POSIX link given) is:

Next, all open streams with unwritten buffered data are flushed, all open streams are closed, …

So, when the program exits, pending output is flushed, regardless of newlines, etc. Similarly, when the file is closed (fclose()), pending output is written:

Any unwritten buffered data for the stream are delivered to the host environment to be written to the file; any unread buffered data are discarded.

And, of course, the fflush() function flushes the output.

The rules quoted in the question are not wholly accurate.

  1. When the buffer is full — this is correct.

  2. When a newline is encountered — this is not correct, though it often applies. If the output device is an 'interactive device', then line buffering is the default. However, if the output device is 'non-interactive' (disk file, a pipe, etc), then the output is not necessarily (or usually) line-buffered.

  3. When there is impending input — this too is not correct, though it is commonly the way it works. Again, it depends on whether the input and output devices are 'interactive'.

The output buffering mode can be modified by calling setvbuf() to set no buffering, line buffering or full buffering.

The standard says (§7.21.3):

?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.

Also, §5.1.2.3 Program execution says:

  • The input and output dynamics of interactive devices shall take place as specified in 7.21.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.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...