C语言 - 标准输出打印顺序

4
代码如下:
printf("u");
write(STDOUT_FILENO, "m", 1);
printf("d\n");

输出: 泥

有人能解释为什么输出是按照这个顺序打印的吗?

3个回答

3

默认情况下,标准输出是按行缓冲的,这意味着printf("u")只会将"u"放入其缓冲区中,直到出现fflush或换行符为止。要按顺序查看输出,请尝试以下操作:

printf("u");
fflush(stdout);
write(STDOUT_FILENO, "m", 1);
printf("d\n");

不,stdout 不是行缓冲的。如果它与终端相关联,则默认情况下它是行缓冲的。如果它与管道或常规文件相关联,则很可能不是。 - William Pursell
@WilliamPursell 你能展示一下那个的参考资料吗? - fluter
谢谢,如果您能指出相关的标准部分,无论是C11、C99还是C89,那将更有说服力。 - fluter
1
@fluter:C11第7.21.3.7节要求,除非确定不是交互设备(如终端),否则stdinstdout不能是完全缓冲的。如果它确实是交互设备,则可以是行缓冲或无缓冲的。如果不是,则可以是完全缓冲的(并且至少在类Unix系统上,可能会是完全缓冲的,正如@WilliamPursell所指出的那样)。 - Crowman
@PaulGriffiths 谢谢! - fluter

2

printf将“u”存储在缓冲区中。 write将数据写入底层文件描述符。下一个printf将“d\n”放入缓冲区。在将来的某个时间点(程序退出时或者当您调用printf足够多次以使缓冲区满),缓冲区将被写入底层文件描述符。


1

通过标准C流输出是有缓冲的。第一次调用printfu存储到缓冲区中,而第二行通过write系统调用直接向系统标准输出文件句柄输出m,最后第二次调用printfd和一个换行符存储在缓冲区中并将缓冲区刷新到系统标准输出句柄上,这可能是因为输出是行缓冲的(如果FILE*与终端相关联,则通常是默认设置),并且\n会导致刷新,或者是因为流在程序正常终止时被刷新。

stderr默认情况下是无缓冲的,请尝试以下操作:

fprintf(stderr, "u");
write(STDERR_FILENO, "m", 1);
fprintf(stderr, "d\n");

这个问题中的“终端”在哪里?请不要混淆stdout和tty。 - William Pursell
@WilliamPursell:我同意,我修改了答案以使其更加精确。 - chqrlie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接