简体   繁体   中英

stdout and stderr in c

Each time I start the program, the message "This message 2" is displayed in a random order relative to other messages.

#include <stdio.h>

int main()
{
    fprintf(stdout,"This is message 1\n");
    fprintf(stderr,"This is message 2\n");
    fprintf(stdout,"This is message 3\n");
    return 0;
}

Examples:

Example 1

Example 2

Why is this happening and how to fix it?

No randomness is displayed in the examples; both show message 2 first, and this is the result of deterministic behavior.

Per C 2018 7.21.3 7, the standard error stream is not fully buffered. This means it is either unbuffered (printed characters are sent as soon as possible) or line buffered (printed characters are sent when a new-line character is printed or sooner). Since "This is message 2\n" ends with a new-line character, both the unbuffered and line buffered modes send it as soon as possible.

Also per 7.21.3 7, the standard output stream is fully buffered if and only if it can be determined not to refer to an interactive device. Thus, we have two possibilities:

  • The stream can be determined to refer to an interactive device. Then it is not fully buffered, so it is unbuffered or line buffered, and the strings ending with new-line characters are sent as soon as possible.
  • The stream can not be determined to refer to an interactive device. Then it is fully buffered, so the strings are held in a buffer until the buffer is full or a flush is requested, which occurs at normal program termination.

Thus the total behavior of the program when the output is going directly to an interactive device is that all strings are sent immediately, so the output will be:

This is message 1
This is message 2
This is message 3

And the total behavior of the program when the output is not going to an interactive device is that message 2 is sent immediately and messages 1 and 3 are held in a buffer until the end of the program, so the output is:

This is message 2
This is message 1
This is message 3

Both cases are deterministic, not random. The output shown in the question is evidence that the IDE is running the program with the standard output captured in some way and presented to the user indirectly (as through a pipe or a redirection to a temporary file) rather than sent directly to the display device.

This can be changed by manually inserting fflush(stdout) calls where you want the standard output to be sent immediately to the associated device or file, or it can be changed by making the standard output stream line-buffered:

setvbuf(stdout, 0, _IOLBF, 0); // Must be before stdout is used.

(You could also use setvbuf to make the standard error stream fully buffered, but that is inadvisable.)

If the IDE is capturing both the standard output stream and the standard error stream in the same way, this will result in the messages appearing in the 1, 2, 3 order. However, it is possible the IDE is capturing the streams separately and displaying the standard error results first, in which case changing the buffering will not change the display.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM