Characters that are written to a stream are normally accumulated and transmitted asynchronously to the file in a block, instead of appearing as soon as they are output by the application program. Similarly, streams often retrieve input from the host environment in blocks rather than on a character-by-character basis. This is called buffering.
If you are writing programs that do interactive input and output using streams, you need to understand how buffering works when you design the user interface to your program. Otherwise, you might find that output (such as progress or prompt messages) doesn't appear when you intended it to, or displays some other unexpected behavior.
This section deals only with controlling when characters are transmitted between the stream and the file or device, and not with how things like echoing, flow control, and the like are handled on specific classes of devices. For information on common control operations on terminal devices, see Chapter 18.
You can bypass the stream buffering facilities altogether by using the low-level input and output functions that operate on file descriptors instead. Chapter 14.
There are three different kinds of buffering strategies:
Characters written to or read from an unbuffered stream are transmitted individually to or from the file as soon as possible.
Characters written to a line buffered stream are transmitted to the file in blocks when a newline character is encountered.
Characters written to or read from a fully buffered stream are transmitted to or from the file in blocks of arbitrary size.
Newly opened streams are normally fully buffered, with one exception: a stream connected to an interactive device such as a terminal is initially line buffered. the section called “Controlling Which Kind of Buffering”, for information on how to select a different kind of buffering. Usually the automatic selection gives you the most convenient kind of buffering for the file or device you open.
The use of line buffering for interactive devices implies that output messages ending in a newline will appear immediately--which is usually what you want. Output that doesn't end in a newline might or might not show up immediately, so if you want them to appear immediately, you should flush buffered output explicitly with fflush, as described in the section called “Flushing Buffers”.
Flushing output on a buffered stream means transmitting all accumulated characters to the file. There are many circumstances when buffered output on a stream is flushed automatically:
When you try to do output and the output buffer is full.
When the stream is closed. the section called “Closing Streams”.
When the program terminates by calling exit. the section called “Normal Termination”.
When a newline is written, if the stream is line buffered.
Whenever an input operation on any stream actually reads data from its file.
If you want to flush the buffered output at another time, call fflush, which is declared in the header file stdio.h. int function>fflush/function> (FILE *stream) This function causes any buffered output on stream to be delivered to the file. If stream is a null pointer, then fflush causes buffered output on all open output streams to be flushed.
This function returns EOF if a write error occurs, or zero otherwise.
int function>fflush_unlocked/function> (FILE *stream) The fflush_unlocked function is equivalent to the fflush function except that it does not implicitly lock the stream.
The fflush function can be used to flush all streams currently opened. While this is useful in some situations it does often more than necessary since it might be done in situations when terminal input is required and the program wants to be sure that all output is visible on the terminal. But this means that only line buffered streams have to be flushed. Solaris introduced a function especially for this. It was always available in the GNU C library in some form but never officially exported.
void function>_flushlbf/function> (void) The _flushlbf function flushes all line buffered streams currently opened.
This function is declared in the stdio_ext.h header.
Compatibility Note: Some brain-damaged operating systems have been known to be so thoroughly fixated on line-oriented input and output that flushing a line buffered stream causes a newline to be written! Fortunately, this "feature" seems to be becoming less common. You do not need to worry about this in the GNU system.
In some situations it might be useful to not flush the output pending for a stream but instead simply forget it. If transmission is costly and the output is not needed anymore this is valid reasoning. In this situation a non-standard function introduced in Solaris and available in the GNU C library can be used.
void function>__fpurge/function> (FILE *stream) The __fpurge function causes the buffer of the stream stream to be emptied. If the stream is currently in read mode all input in the buffer is lost. If the stream is in output mode the buffered output is not written to the device (or whatever other underlying storage) and the buffer the cleared.
This function is declared in stdio_ext.h.
After opening a stream (but before any other operations have been performed on it), you can explicitly specify what kind of buffering you want it to have using the setvbuf function. The facilities listed in this section are declared in the header file stdio.h. int function>setvbuf/function> (FILE *stream, char *buf, int mode, size_t size) This function is used to specify that the stream stream should have the buffering mode mode, which can be either _IOFBF (for full buffering), _IOLBF (for line buffering), or _IONBF (for unbuffered input/output).
If you specify a null pointer as the buf argument, then setvbuf allocates a buffer itself using malloc. This buffer will be freed when you close the stream.
Otherwise, buf should be a character array that can hold at least size characters. You should not free the space for this array as long as the stream remains open and this array remains its buffer. You should usually either allocate it statically, or malloc (the section called “Unconstrained Allocation”) the buffer. Using an automatic array is not a good idea unless you close the file before exiting the block that declares the array.
While the array remains a stream buffer, the stream I/O functions will use the buffer for their internal purposes. You shouldn't try to access the values in the array directly while the stream is using it for buffering.
The setvbuf function returns zero on success, or a nonzero value if the value of mode is not valid or if the request could not be honored.
int function>_IOFBF/function> The value of this macro is an integer constant expression that can be used as the mode argument to the setvbuf function to specify that the stream should be fully buffered.
int function>_IOLBF/function> The value of this macro is an integer constant expression that can be used as the mode argument to the setvbuf function to specify that the stream should be line buffered.
int function>_IONBF/function> The value of this macro is an integer constant expression that can be used as the mode argument to the setvbuf function to specify that the stream should be unbuffered.
int function>BUFSIZ/function> The value of this macro is an integer constant expression that is good to use for the size argument to setvbuf. This value is guaranteed to be at least 256.
The value of BUFSIZ is chosen on each system so as to make stream I/O efficient. So it is a good idea to use BUFSIZ as the size for the buffer when you call setvbuf.
Actually, you can get an even better value to use for the buffer size by means of the fstat system call: it is found in the st_blksize field of the file attributes. the section called “The meaning of the File Attributes”.
Sometimes people also use BUFSIZ as the allocation size of buffers used for related purposes, such as strings used to receive a line of input with fgets (the section called “Character Input”). There is no particular reason to use BUFSIZ for this instead of any other integer, except that it might lead to doing I/O in chunks of an efficient size.
void function>setbuf/function> (FILE *stream, char *buf) If buf is a null pointer, the effect of this function is equivalent to calling setvbuf with a mode argument of _IONBF. Otherwise, it is equivalent to calling setvbuf with buf, and a mode of _IOFBF and a size argument of BUFSIZ.
The setbuf function is provided for compatibility with old code; use setvbuf in all new programs.
void function>setbuffer/function> (FILE *stream, char *buf, size_t size) If buf is a null pointer, this function makes stream unbuffered. Otherwise, it makes stream fully buffered using buf as the buffer. The size argument specifies the length of buf.
This function is provided for compatibility with old BSD code. Use setvbuf instead.
void function>setlinebuf/function> (FILE *stream) This function makes stream be line buffered, and allocates the buffer for you.
This function is provided for compatibility with old BSD code. Use setvbuf instead.
It is possible to query whether a given stream is line buffered or not using a non-standard function introduced in Solaris and available in the GNU C library.
int function>__flbf/function> (FILE *stream) The __flbf function will return a nonzero value in case the stream stream is line buffered. Otherwise the return value is zero.
This function is declared in the stdio_ext.h header.
Two more extensions allow to determine the size of the buffer and how much of it is used. These functions were also introduced in Solaris.
size_t function>__fbufsize/function> (FILE *stream) The __fbufsize function return the size of the buffer in the stream stream. This value can be used to optimize the use of the stream.
This function is declared in the stdio_ext.h header.
size_t function>__fpending/function> (FILE *stream) The __fpendingfunction returns the number of bytes currently in the output buffer. For wide-oriented stream the measuring unit is wide characters. This function should not be used on buffers in read mode or opened read-only.
This function is declared in the stdio_ext.h header.