FILE type is an opaque type which keeps a buffer inside, used to streaming data. Some streams are "line buffered", like stdout, which means they flush the contents of this buffer if it is full OR if a '\n' is found. When you do:
Code:
printf( "\nHello" );
printf() will add every single char to the stdout stream, but when a '\n' is writen, the entire buffer is flushed.
Code:
+---------- flushes the buffer and writes '\n'.
| +------ just add those to the buffer, not flushing.
V VVVVV
"\nHello"
The "Hello" part is added to the buffer inside stdout, and is kept there.
The next printf: printf( " world\n" );, adds " world" to the buffer, but when '\n' is found, the entire buffer is flushed and '\n' is writen.
That's why is advisable to call fflush() when there's no '\n' at the end of the string if you want it immediatly printed (or writen to file).
Notice that stdout is line buffered, but stderr isn't. This is controlled by setvbuf() function:
Code:
int setvbuf( FILE *stream, char *buf, int mode, size_t size );
With this function you can setup your own buffer and tell if the stream is line buffered or not. Like that:
Code:
static char buffer[32768]; // 32 KiB
setvbuf( stdout, buffer, _IOLBF, sizeof buffer );
Now we have stdout with a big buffer and it is line buffered (_IOLBF) -- The default buffer size is BUFSIZ (in my system, 8 KiB). You can change only the buffering scheme with:
Code:
// After that, stdout isn't line buffered, but fully buffered,
// and the original buffer is kept.
setvbuf( stdout, NULL, _IOFBF, 0 );
"Fully buffered" means the buffer will be flushed when it is full. There's a _IONBF too, which means no buffering (all chars are flushed immediately).
PS: fopen() always create an object to a line buffered stream if "t" is informed in the mode or a fully buffered if "b".
PS2: This buffering scheme is useful to keep functions dealing with streams fast. write(), which deals with file descriptors, isn't buffered and can block the thread until all data is writen.
PS3: If you use an "external" buffer, make sure it still exists after program termination... This is INVALID:
Code:
int main( void )
{
char buffer[BUFSIZ];
setvbuf( stdout, buffer, _IOLBF, sizeof buffer );
printf( "ok\n" );
// ops... buffer is local to main(). If will be allocated in the
// stack and don't exist anymore after main returns!
}
That's why I made the buffer static (in the example before this one).