为什么printf在调用之后不刷新,除非换行符在格式化string中?

为什么printf在调用之后不刷新,除非换行符在格式化string中? 这是POSIX的行为? 我怎样才能让printf每次立即刷新?

stdoutstream被缓冲,所以只会在到达换行符(或者被告知)时显示缓冲区中的内容。 你有几个select立即打印:

使用fprintf打印到stderr:

 fprintf(stderr, "I will be printed immediately"); 

在需要使用fflush时刷新stdout:

 printf("Buffered, will be flushed"); fflush(stdout); // Will now print everything in the stdout buffer 

编辑 :从下面的Andy Ross的评论,你也可以使用setbuf禁用标准输出缓冲:

 setbuf(stdout, NULL); 

不,这不是POSIX行为,而是ISO行为(嗯,这 POSIX的行为,但只要符合ISO标准)。

如果可以检测到标准输出是指交互式设备,则标准输出是行缓冲的,否则它是完全缓冲的。 所以有些情况下printf不会被刷新,即使它得到一个换行符,例如:

 myprog >myfile.txt 

这对于效率是有意义的,因为如果你与用户交互,他们可能希望看到每一行。 如果你将输出发送到一个文件,很可能是另一端没有用户(尽pipe不是不可能的,他们可能是拖曳文件)。 现在你可以争辩说,用户想看到每一个angular色,但有两个问题。

首先是效率不高。 第二个原因是ANSI C的主要任务是对现有的行为进行编纂,而不是发明新的行为,而这些devise决定是在ANSI开始这个过程之前就做出的。 即使ISO现在在改变标准中的现有规则时也非常谨慎。

至于如何处理这个问题,如果你立即看到每个输出调用之后fflush (stdout)如果你fflush (stdout) ,那么这个问题就解决了。

或者,您可以在stdout上使用setvbuf之前,将其设置为无缓冲,您将不必担心将所有这些fflush行添加到您的代码:

 setvbuf (stdout, NULL, _IONBF, BUFSIZ); 

请记住,如果要将输出发送到文件,可能会影响性能。 同时请记住,对此的支持是由实现定义的,而不是由标准保证的。

ISO C99第7.19.3/3节是相关位:

当一个数据stream没有缓冲的时候 ,字符应该尽可能的从源头或目的地出现。 否则,字符可以积累并作为一个块被传送到主机环境或从主机环境传送。

当一个stream被完全缓冲时 ,当缓冲区被填满时,字符被打算作为一个块被传输到主机环境或从主机环境传输。

当一个stream是行缓冲的时候 ,当遇到一个换行符时 ,字符被打算作为一个块被传送到主机环境或从主机环境传送出去。

此外,当填充缓冲区,当在非缓冲stream上请求input时,或者在需要从主机环境传输字符的线路缓冲stream上请求input时,字符意图作为块被传输到主机环境。

对这些特征的支持是由实现定义的,并可能通过setbufsetvbuf函数来影响。

这可能是因为效率,如果你有多个程序写入一个单一的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 

请注意,甚至不保证在换行符上刷新,所以如果刷新对你来说很重要,你应该明确地刷新。

立即刷新调用fflush(stdout)fflush(NULL)NULL表示刷新所有内容)。

stdout被缓冲,因此只有在打印换行符后才会输出。

要获得即时输出,可以:

  1. 打印到stderr。
  2. 使标准输出无缓冲。

注意:Microsoft运行时库不支持行缓冲,因此printf("will print immediatelly to terminal")

http://msdn.microsoft.com/en-us/library/86cebhfs.aspx

默认情况下,stdout是行缓冲的,stderr没有被缓冲,文件被完全缓冲。

您可以将fprintf改为stderr,而不是缓冲区。 或者你可以刷新标准输出,当你想要的。 或者你可以设置标准输出为无缓冲。

使用setbuf(stdout, NULL); 禁用缓冲。