The stdout stream is line buffered by default, so will only display what's in the buffer after it reaches a newline (or when it's told to). You have a few options to print immediately:
Print to
stderrinstead usingfprintf(stderris unbuffered by default):fprintf(stderr, "I will be printed immediately");Flush
stdoutwhenever you need it to usingfflush:printf("Buffered, will be flushed"); fflush(stdout); // Will now print everything in the stdout bufferDisable buffering on stdout by using
setbuf:setbuf(stdout, NULL);Or use the more flexible
setvbuf:setvbuf(stdout, NULL, _IONBF, 0);
The stdout stream is line buffered by default, so will only display what's in the buffer after it reaches a newline (or when it's told to). You have a few options to print immediately:
Print to
stderrinstead usingfprintf(stderris unbuffered by default):fprintf(stderr, "I will be printed immediately");Flush
stdoutwhenever you need it to usingfflush:printf("Buffered, will be flushed"); fflush(stdout); // Will now print everything in the stdout bufferDisable buffering on stdout by using
setbuf:setbuf(stdout, NULL);Or use the more flexible
setvbuf:setvbuf(stdout, NULL, _IONBF, 0);
No, it's not POSIX behaviour, it's ISO C behaviour (well, it is POSIX behaviour but only insofar as they conform to ISO C).
Standard output is line buffered if it can be detected to refer to an interactive device, otherwise it's fully buffered. So there are situations where printf won't flush, even if it gets a newline to send out, such as:
myprog >myfile.txt
This makes sense for efficiency since, if you're interacting with a user, they probably want to see every line. If you're sending the output to a file, it's most likely that there's not a user at the other end (though not impossible, they could be tailing the file). Now you could argue that the user wants to see every character but there are two problems with that.
The first is that it's not very efficient. The second is that the original ANSI C 89 mandate was to primarily codify existing behaviour, rather than invent new behaviour, and those design decisions were made long before ANSI started the process. Even ISO C nowadays treads very carefully when changing existing rules in the standards.
As to how to deal with that, if you fflush (stdout) after every output call that you want to see immediately, that will solve the problem.
Alternatively, you can use setvbuf before operating on stdout, to set it to unbuffered and you won't have to worry about adding all those fflush lines to your code:
setvbuf (stdout, NULL, _IONBF, BUFSIZ);
Just keep in mind that may affect performance quite a bit if you are sending the output to a file. Also keep in mind that support for this is implementation-defined, not guaranteed by the standard.
ISO C99 section 7.19.3/3 is the relevant bit:
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
setbufandsetvbuffunctions.
shell - Flush the pipe/printf buffers externally for already running process with known PID - Unix & Linux Stack Exchange
When does `Printf.printf` flush?
Flushing buffers in C - Stack Overflow
Flush buffer created by printf retargeting
I ran into an interesting behaviour that I can't seem to find a complete answer to when I searched..
Let's say I have this piece of code:
do {
printf("HEY! ");
} while (1);If this is run as part of a program executed in the terminal, it would just print on the terminal screen forever. However... if I add this to the code:
do {
printf("HEY! ");
// read a single character into c
read(STDIN_FILENO, &c, 1);
} while (1);Suddenly printf buffer will never flush and therefore never print to the screen. Additionally, if I add one more line:
do {
printf("HEY! ");
// read a single character into c
read(STDIN_FILENO, &c, 1);
buffer[0] = c;
// write the read character to standard output
write(STDOUT_FILENO, b, 1);
} while (1);
The read-in character will be sent to stdout and will be outputted to the screen each time a key is pressed. However, in this case the printf() local buffer will still never flush to the screen.
In fact it seems that as long as I have a call to read() anywhere in the function printf() will do nothing no matter where I have placed it in the function code (above or below). The only way I can get it to flush is it I make the explicit call fflush(stdout).
So I have two questions:
-
Why is this behaviour happening, or in other words, what exactly (implicitly) causes the
printf()buffer to flush? What causes this to not happen once a call to read() is made? -
Why does a call to
fflush(stdout)flush the buffer ofprint()? Is this buffer not local to the function, which then would not cause it to flush when we explicitly flush stdout?
gdb -p PID -batch -ex 'p fflush(stdout)'
As with any debugging and hacking, YMMV.
Do you have access to the source of the running programs?
Forcing a flush of an arbitrary executable is, while not theoretically impossible, very difficult. You would need to find the fflush function in the code and the stdout argument, then interrupt the execution of the program, arrange for the call to fflush, then continue execution. If the program is using a shared library, that at least makes the first part easier, finding fflush and stdout, but you still need to simulate the call. Also, for an unknown binary, you can't know whether it used stdio or whether it implements its own buffering mechanism. Knowing the path of the output file will not help you.
You can try to use gdb, then use the attach command to attach to the process. Maybe gdb can call the fflush function.
If you have the source to the program, implement a signal handler that flushes the buffer and just send the signal when you want the buffer flushed.
You can try a pipe, maybe the programs don't buffer if the output is a pipe. Change it to
./program | your_program > out.bin
Your program can accept the input, buffer it and flush the buffer when it receives a signal. It would still add CPU overhead, but not disk overhead.
No, the standard says that stdout is initially fully buffered if the output device can be determined to be a non-interactive one.
It means that, if you redirect stdout to a file, it won't flush on newline. If you want to try and force it to line-buffered, use setbuf or setvbuf.
The relevant part of C99, 7.19.3 Files, paragraph 7, states:
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.
Just keep in mind section 5.1.2.3/6:
What constitutes an interactive device is implementation-defined.
It is flushed if the output device is an interactive one e.g., a terminal.
You have to flush the output buffer in case the output device can be determined to be non-interactive e.g., a file. New line does not do that automatically.
For details see paxdiablo's answer.
main() {
printf("%s", "olaaaaaa");
sleep(5);
}If printf fuction does not flush how does printf prints something before the sleep finish? It isn't suposed to flush stdout only when the program finish, recive a new line (\n) or when reach the max buffer size?