buffering modes and fflush
/ fflush -> EFF-flush /
When does the bucket actually get emptied into the house? A stdio stream collects your bytes in a buffer, but you need to know the rule for when it pours that buffer out to the kernel. There are three rules, called buffering modes, plus a button you can press yourself to force a pour right now.
The three modes are: fully buffered, where bytes accumulate until the buffer is full (typically a few KiB) and only then get written - the default for ordinary files because it maximizes efficiency; line buffered, where the buffer is flushed every time a newline is written - the usual default for stdout when it is connected to a terminal, so you see each line as it is printed; and unbuffered, where every write goes straight through immediately - the default for stderr, so error messages are never trapped behind a buffer when the program crashes. You can set the mode yourself with setvbuf() right after opening. The manual override is fflush(stream): it forces whatever is currently in that stream's buffer out to the kernel at once. fflush(NULL) flushes every output stream. Note: flushing pushes data from the stdio buffer into the kernel; it does not guarantee the data is on the physical disk - that needs fsync() at the descriptor level.
Why it matters: this is the single most common confusion for beginners. A program that does printf("working...") with no newline, then runs a long loop, may show nothing on screen because the line was never flushed - the work is happening, the message is just stuck in the buffer. Calling fflush(stdout) fixes it. The same buffering means that if a program crashes, un-flushed output is lost. Knowing the mode of each stream, and reaching for fflush when timing matters, turns 'why is nothing printing?' into a non-mystery.
printf("working..."); /* no newline: may stay stuck in the buffer */ fflush(stdout); /* force it to the kernel now, so it shows */ long_running_work(); /* meanwhile the message is already visible */
Without the fflush, the message can stay invisible until the next newline, fclose, or normal exit.
fflush moves data from the stdio buffer to the kernel only - it is NOT the same as data hitting the disk. For real durability you also need fsync() on the descriptor. fflush on an input stream is undefined behavior in standard C; it is meaningful only for output.