除非换行符在格式字符串中,为什么 printf 在调用后不会刷新?这是POSIX的行为吗?我怎么能每次都立即冲洗 printf ?
printf
要立即刷新呼叫 fflush(stdout) 或 fflush(NULL) ( NULL 表示刷新所有内容) .
fflush(stdout)
fflush(NULL)
NULL
默认情况下,stdout是行缓冲的,stderr是无缓冲的,文件是完全缓冲的 .
你可以fprintf到stderr,这是无缓冲的 . 或者你可以在你想要的时候冲洗stdout . 或者您可以将stdout设置为无缓冲 .
stdout 流是缓冲的,因此只显示's in the buffer after it reaches a newline (or when it'告诉的内容) . 您可以选择立即打印:
stdout
使用 fprintf 打印到stderr:
fprintf
fprintf(stderr, "I will be printed immediately");
无论何时需要使用 fflush ,都要刷新标准输出:
fflush
printf("Buffered, will be flushed"); fflush(stdout); // Will now print everything in the stdout buffer
Edit :从下面的Andy Ross的评论中,您还可以使用 setbuf 禁用stdout上的缓冲:
setbuf
setbuf(stdout, NULL);
这可能是因为效率,因为如果你有多个程序写入单个TTY,这样你就不会在一行上交换字符 . 因此,如果程序A和B正在输出,您通常会得到:
program A output program B output program B output program A output program B output
这很糟糕,但它比
proprogrgraam m AB ououtputputt prproogrgram amB A ououtputtput program B output
请注意,它甚至不能保证在换行符上刷新,因此如果刷新对您很重要,则应明确刷新 .
不,它是's not POSIX behaviour, it'的ISO行为(嗯,这是POSIX行为,但只是在它们符合ISO的范围内) .
如果可以检测到标准输出是指参考交互式设备,则标准输出是行缓冲的,否则它是完全缓冲的 . 所以有些情况下 printf 不会刷新,即使它有一个换行符,例如:
myprog >myfile.txt
这对于效率是有意义的,因为如果你将输出发送到文件,它不是另一端的用户(虽然不是不可能,但它们可能正在拖尾文件) . 现在你可以争辩说用户想要看到每个角色但是有两个问题 .
首先是它效率不高 . 第二个原因是ANSI C的原始授权主要是对现有行为进行编码,而不是发明新行为,而这些设计决策早在ANSI启动过程之前就做出了 . 在改变标准中的现有规则时,即使ISO现在也非常谨慎 .
至于如何处理,如果你想在每次输出调用之后 fflush (stdout) ,那将解决问题 .
fflush (stdout)
或者,您可以在 stdout 之前使用 setvbuf ,将其设置为无缓冲,您不必担心将所有这些 fflush 行添加到您的代码中:
setvbuf
setvbuf (stdout, NULL, _IONBF, BUFSIZ);
请记住,如果要将输出发送到文件,可能会影响性能 . 另请注意,对此的支持是实现定义的,不受标准保证 .
ISO C99部分 7.19.3/3 是相关位:
7.19.3/3
当流未缓冲时,字符应尽快从源或目标出现 . 否则,可以将字符作为块累积并发送到主机环境或从主机环境发送 . 当流被完全缓冲时,当填充缓冲区时,字符旨在作为块传输到主机环境或从主机环境传输 . 当流被行缓冲时,当遇到换行符时,字符将作为块传输到主机环境或从主机环境传输 . 此外,当填充缓冲区,在无缓冲流上请求输入时,或者在需要从主机环境传输字符的行缓冲流上请求输入时,字符旨在作为块传输到主机环境 . . 对这些特性的支持是实现定义的,可能会受到setbuf和setvbuf函数的影响 .
stdout是缓冲的,因此只会在打印换行符后输出 .
要获得即时输出,请:
打印到stderr .
使stdout无缓冲 .
使用 setbuf(stdout, NULL); 禁用缓冲 .
注意:Microsoft运行时库不支持行缓冲,因此 printf("will print immediatelly to terminal") :
printf("will print immediatelly to terminal")
http://msdn.microsoft.com/en-us/library/86cebhfs.aspx
9 回答
要立即刷新呼叫
fflush(stdout)
或fflush(NULL)
(NULL
表示刷新所有内容) .默认情况下,stdout是行缓冲的,stderr是无缓冲的,文件是完全缓冲的 .
你可以fprintf到stderr,这是无缓冲的 . 或者你可以在你想要的时候冲洗stdout . 或者您可以将stdout设置为无缓冲 .
stdout
流是缓冲的,因此只显示's in the buffer after it reaches a newline (or when it'告诉的内容) . 您可以选择立即打印:使用
fprintf
打印到stderr:无论何时需要使用
fflush
,都要刷新标准输出:Edit :从下面的Andy Ross的评论中,您还可以使用
setbuf
禁用stdout上的缓冲:这可能是因为效率,因为如果你有多个程序写入单个TTY,这样你就不会在一行上交换字符 . 因此,如果程序A和B正在输出,您通常会得到:
这很糟糕,但它比
请注意,它甚至不能保证在换行符上刷新,因此如果刷新对您很重要,则应明确刷新 .
不,它是's not POSIX behaviour, it'的ISO行为(嗯,这是POSIX行为,但只是在它们符合ISO的范围内) .
如果可以检测到标准输出是指参考交互式设备,则标准输出是行缓冲的,否则它是完全缓冲的 . 所以有些情况下
printf
不会刷新,即使它有一个换行符,例如:这对于效率是有意义的,因为如果你将输出发送到文件,它不是另一端的用户(虽然不是不可能,但它们可能正在拖尾文件) . 现在你可以争辩说用户想要看到每个角色但是有两个问题 .
首先是它效率不高 . 第二个原因是ANSI C的原始授权主要是对现有行为进行编码,而不是发明新行为,而这些设计决策早在ANSI启动过程之前就做出了 . 在改变标准中的现有规则时,即使ISO现在也非常谨慎 .
至于如何处理,如果你想在每次输出调用之后
fflush (stdout)
,那将解决问题 .或者,您可以在
stdout
之前使用setvbuf
,将其设置为无缓冲,您不必担心将所有这些fflush
行添加到您的代码中:请记住,如果要将输出发送到文件,可能会影响性能 . 另请注意,对此的支持是实现定义的,不受标准保证 .
ISO C99部分
7.19.3/3
是相关位:stdout是缓冲的,因此只会在打印换行符后输出 .
要获得即时输出,请:
打印到stderr .
使stdout无缓冲 .
使用
setbuf(stdout, NULL);
禁用缓冲 .注意:Microsoft运行时库不支持行缓冲,因此
printf("will print immediatelly to terminal")
:http://msdn.microsoft.com/en-us/library/86cebhfs.aspx