When you write characters to a stream, they are not usually stored in
the file on a character-by-character basis as soon as they are written
to the stream, but instead are accumulated in a buffer first, then
written to the file in a block when certain conditions are met. (A
buffer is an area of the computer's memory that acts as a temporary
holding area for input or output.) Similarly, when you are reading
characters from a stream, they are often buffered, or stored in a
buffer first.
It's important to understand how buffering works, or you may find your
programs behaving in an unexpected way, reading and writing characters
when you do not expect them to. (You can bypass stream buffering entirely,
however, by using low-level rather than high-level file routines.
See Low-level file routines, for more information.)
There are three main kinds of buffering you should know about:
No buffering:
When you write characters to an unbuffered stream, the operating system
writes them to the file as soon as possible.
Line buffering:
When you write characters to a line-buffered stream, the operating
system writes them to the file when it encounters a newline character.
Full buffering:
When you write characters to a fully-buffered stream, the operating system
writes them to the file in blocks of arbitrary size.
Most streams are fully buffered when you open them, and this is usually
the best solution. However, streams connected to interactive devices
such as terminals are line-buffered when you open them; yes, this means
that stdin and stdout are line-buffered.
Having stdin and stdout be line-buffered is convenient,
because most meaningful chunks of data you write to them are terminated
with a newline character. In order to ensure that the data you read
from or write to a fully-buffered stream shows up right away, use the
fflush function. In the jargon, this is called flushing
the stream. Flushing moves the characters from the buffer to the file,
if they haven't already been moved. After the move, other functions can
then work on the characters.1
To use fflush, simply pass the function the stream you want to
flush. The fflush function returns 0 if successful, or the value
EOF (which is a macro defined in the GNU C Library) if there was
a write error.
Note that using fflush is not always necessary; output is flushed
automatically when you try to write and the output buffer is already
full, when the stream is closed, when the program exits, when an input
operation on a stream actually reads data from the file, and of course,
when a newline is written to a line-buffered stream.
(See fputs, for a code example that uses fflush.)
Footnotes
Strictly speaking, there are
multiple levels of buffering on a GNU system. Even after flushing
characters to a file, data from the file may remain in memory, unwritten
to disk. On GNU systems, there is an independently-running system
program, or daemon, that periodically commits relevant data still
in memory to disk. Under GNU/Linux, this daemon is called
bdflush.