Reputation: 3879
While writing a c program I encountered a puzzling behavior with printf and write. It appears that write is in some cases called before printf even though it is after it in the code (is printf asynchronous?). Also if there are two lines in the printf, output after that appears to be inserted between them. My question is what causes this behavior and how can I know what will happen when? What about other output functions (ex. puts) - can I look out for something in the documentation to know how they will behave with others. Example code:
#include <unistd.h>
#include <stdio.h>
int main(void)
{
write(STDOUT_FILENO, "1.", 2);
printf("2.");
write(STDOUT_FILENO, "3.", 2);
printf("4.\n5.");
printf("6.");
write(STDOUT_FILENO, "7.", 2);
return 0;
}
Output:
1.3.2.4.
7.5.6.
Upvotes: -1
Views: 1965
Reputation: 72717
In addition to the mentioned use of fflush()
after each output operation, you could also make stdout
unbuffered with
setvbuf(stdout, NULL, _IONBF, 0);
This way, all output by printf
, puts
, putchar
, ... would appear in order with write
output (without the need to sprinkle a lot of fflush()s around).
Upvotes: 2
Reputation: 30926
write
is not buffered printf
is. Whenever you use write
it gets to the console - but printf
is outputted when it gets \n
here, because then the buffer is flushed.
That's why after 1.3.
you see 2.4.
You can flush the output by using fflush(stdout)
right after the printf
calls. (Steve Summit
commented this)
You may wonder there is no other \n
after that printf
so why do those characters are flushed?
On program termination the output buffer is also flushed. That is what causes the rest of the printf
outputs to appear. The setvbuf()
function may only be used after opening a stream and before any other operations have been performed on it.
Also as zwol
mentioned you can turn of line bufferng of stdout
using this before making any other call to standard I/O functions.
setvbuf(stdout, 0, _IONBF, 0)
^^^
causes input/output to be unbuffered
Upvotes: 4