首页 文章

除非换行符在格式字符串中,为什么printf在调用后不会刷新?

提问于
浏览
456

除非换行符在格式字符串中,为什么 printf 在调用后不会刷新?这是POSIX的行为吗?我怎么能每次都立即冲洗 printf

9 回答

  • 12

    要立即刷新呼叫 fflush(stdout)fflush(NULL)NULL 表示刷新所有内容) .

  • 21

    默认情况下,stdout是行缓冲的,stderr是无缓冲的,文件是完全缓冲的 .

  • 108

    你可以fprintf到stderr,这是无缓冲的 . 或者你可以在你想要的时候冲洗stdout . 或者您可以将stdout设置为无缓冲 .

  • 24

    stdout 流是缓冲的,因此只显示's in the buffer after it reaches a newline (or when it'告诉的内容) . 您可以选择立即打印:

    使用 fprintf 打印到stderr:

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

    无论何时需要使用 fflush ,都要刷新标准输出:

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

    Edit :从下面的Andy Ross的评论中,您还可以使用 setbuf 禁用stdout上的缓冲:

    setbuf(stdout, NULL);
    
  • 8

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

    请注意,它甚至不能保证在换行符上刷新,因此如果刷新对您很重要,则应明确刷新 .

  • 589

    不,它是's not POSIX behaviour, it'的ISO行为(嗯,这是POSIX行为,但只是在它们符合ISO的范围内) .

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

    myprog >myfile.txt
    

    这对于效率是有意义的,因为如果你将输出发送到文件,它不是另一端的用户(虽然不是不可能,但它们可能正在拖尾文件) . 现在你可以争辩说用户想要看到每个角色但是有两个问题 .

    首先是它效率不高 . 第二个原因是ANSI C的原始授权主要是对现有行为进行编码,而不是发明新行为,而这些设计决策早在ANSI启动过程之前就做出了 . 在改变标准中的现有规则时,即使ISO现在也非常谨慎 .

    至于如何处理,如果你想在每次输出调用之后 fflush (stdout) ,那将解决问题 .

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

    setvbuf (stdout, NULL, _IONBF, BUFSIZ);
    

    请记住,如果要将输出发送到文件,可能会影响性能 . 另请注意,对此的支持是实现定义的,不受标准保证 .

    ISO C99部分 7.19.3/3 是相关位:

    当流未缓冲时,字符应尽快从源或目标出现 . 否则,可以将字符作为块累积并发送到主机环境或从主机环境发送 . 当流被完全缓冲时,当填充缓冲区时,字符旨在作为块传输到主机环境或从主机环境传输 . 当流被行缓冲时,当遇到换行符时,字符将作为块传输到主机环境或从主机环境传输 . 此外,当填充缓冲区,在无缓冲流上请求输入时,或者在需要从主机环境传输字符的行缓冲流上请求输入时,字符旨在作为块传输到主机环境 . . 对这些特性的支持是实现定义的,可能会受到setbuf和setvbuf函数的影响 .

  • 10

    stdout是缓冲的,因此只会在打印换行符后输出 .

    要获得即时输出,请:

    • 打印到stderr .

    • 使stdout无缓冲 .

  • 10

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

  • 6

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

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

相关问题