views:

1498

answers:

4
#include <stdio.h>
#define MAXLEN 256

int main() {
  int n;
  char buf[MAXLEN];
  while((n = read(0,buf,sizeof(buf))) != 0){
    printf("n: %d:",n);
    write(1,buf,n);
  }
  return 1;
}

The output of the program is

read
read
write
write
n: 5:n: 6:

The output of printf comes after pressing Ctrl+D at the standard input and not alongwith the subsequent reads. Y does this happen?

A: 

Printf is using stdio and it is buffered. Push it out by sending a changing to "n: %d:\n"

Tim Williscroft
Either that, or don't mix output channels -- that is, use one and the same function to output all content.
Kim Gräsman
\n is not guaranteed to flush it.
EFraim
stdout is line buffered unless it it directed to an non interactive device.
AProgrammer
+8  A: 

Printf is buffered.

You can force printf to 'flush' its buffer using the fflush call:

#include <stdio.h>
#define MAXLEN 256

int main() {
  int n;
  char buf[MAXLEN];
  while((n = read(0,buf,sizeof(buf))) != 0){
    printf("n: %d:",n);
    fflush(stdout); /* force it to go out */
    write(1,buf,n);
  }
  return 1;
}

In general, printf() being buffered is a good thing. Unbuffered output, particularly to visible consoles that require screen updates and such, is slow. Slow enough that an application that is printf'ing a lot can be directly slowed down by it (especially on the Windows platform; Linux and unixes are typically impacted less).

However, printf() being buffered does bite you if you also fprintf(stderr,) - stderr is deliberately unbuffered. As a consequence, you may get your messages with some printf() missing; if you write to another FILE handle that is also associated with the terminal, and might be unbuffered, make sure you first explicitly fflush(stdout).

Will
You can also change the buffering mode with setvbuf() before doing any IO.
AProgrammer
+1  A: 

The manpage for fgets tells me:

It is not advisable to mix calls to input functions from the stdio library with low-level calls to read(2) for the file descriptor associ‐ ated with the input stream; the results will be undefined and very probably not what you want.

So the best solution would be not to to use write and printf on the same descriptor.

kmm
A: 

Use fwrite (streams version) rather than write.

Note that, while is associated with file number 1, it isn't the same thing.