In this program, the output is unordered and as stdout
is linked to the terminal the output of fprintf()
containing stdout
is written to the terminal, but why the output of the fprintf()
containing stderr
also printed to the terminal? Rather it should be printed to the stderr
file handle. Is stderr
also linked to the terminal?
CODE
#include <stdio.h>
#include <unistd.h>
int main() {
fprintf(stdout, "This is to stdout. ");
fprintf(stderr, "This is to stderr. ");
fprintf(stdout, "This is also to stdout. ");
return 0;
}
OUTPUT (in online compiler)
This is to stderr. This is to stdout. This is also to stdout.
Also I would like to ask one thing. Why the output is different in my Visual Studio Code IDE
.
VS CODE OUTPUT
This is to stdout. This is to stderr. This is also to stdout.
Here VS CODE gives different output from the online compiler. Why it is so and how to fix this?
In your C implementation, when output is to a terminal, stdout
is line buffered, and stderr
is unbuffered. This means that output to stderr
is sent to the terminal immediately, whereas output to stdout
is sent only when:
stdout
will appear before the user is supposed to type a response),fflush
).When a stream is buffered, characters may be accumulated in a buffer and sent or received as a block when the buffer is full. Buffering is used because the operations to send or receive data have a large overhead, so executing them for each character sent, or each partial line, would be expensive in terms of resources such as execution time and energy. Sending many characters from a buffer in one operation is more efficient.
In addition to unbuffered and line buffered, there is also fully buffered, in which characters are intended to be sent or received only when the buffer is full. The C standard describes buffering in C 2018 7.21.3 3.
In 7.21.3 7, the standard tells us the standard error stream is not fully buffered. It may be unbuffered or line buffered. Your C implementation apparently chooses to make it unbuffered, so error messages will be written to the terminal immediately. That paragraph also tells us that standard input and standard output are fully buffered only if the stream “can be determined not to refer to an interactive device.” For example, if you redirect output to a file instead of the terminal, it does not refer to an interactive device, and it should be fully buffered. When output is known to be going to an interactive device, it should not be fully buffered. It may be line buffered or unbuffered, and your C implementation apparently chooses to make it line buffered.
If you modify the program to include \n
at the end of each string it prints, you will see them in order, because the unbuffered and line buffered streams will print each complete line (characters ending with a new-line character) in order.
You can also use setvbuf
to change the buffering mode of a stream after it is open and before any other operation is performed on it. For example, to set stdout
to unbuffered, you can use:
int result = setvbuf(stdout, NULL, _IONBF, 0);
if (result != 0)
fprintf(stderr, "Error, setvbuf returned %d.\n", result);
setvbuf
is specified in C 2018 7.21.5.6. _IOFBF
requests fully buffered, and _IOLBF
requests line buffered. (The second and fourth parameters are for providing your own array to use as the buffer and its length.)
1 Specifically, requesting input (as by calling fgetc
or scanf
) on an unbuffered stream or on a line buffered stream that “requires the transmission of characters from the host environment” will trigger flushing of line buffered output.