mdatsev
mdatsev

Reputation: 3879

write and printf out of order output

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

Answers (2)

Jens
Jens

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

user2736738
user2736738

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

Related Questions