【问题标题】:Difference between puts() and printf() in C while using sleep()使用 sleep() 时 C 中 puts() 和 printf() 的区别
【发布时间】:2013-01-18 18:28:13
【问题描述】:

我想知道使用 sleep() 函数时 puts() 和 printf() 函数之间的区别。

这是我的代码(C语言):

printf("hello, world");
sleep(1);
printf("Good, bye!");

程序编译运行后,似乎会先休眠,然后打印“hello, worldGood, bye!”

但是,如果使用 puts() 而不是 printf(),它将打印“hello, world”然后休眠,最后打印“Good, bye”。

puts("hello, world");
sleep(1);
puts("Good, bye!);

【问题讨论】:

    标签: c sleep puts


    【解决方案1】:

    这是因为缓冲 - 默认情况下,标准输出缓冲到每个新行。 printf() 不包含换行符,因此不会刷新输出。 puts() 包含换行符,因此输出被刷新。

    您可以通过换行来使printf() 刷新:

    printf("hello, world\n");
    

    或直接致电fflush()

    fflush(stdout);
    

    有关缓冲的更多信息,请参阅setbuf() 的手册页:

    The three types of buffering available are unbuffered, block buffered, and
       line buffered.  When an output stream is unbuffered, information appears on
       the destination file or terminal as soon as written; when it is block 
       buffered many characters are saved up and written as a block; when it 
       is line buffered characters are saved up until a newline is output or input
       is read from any stream attached to a terminal device (typically stdin).
       ....
       If a stream refers to a terminal (as stdout normally does) it is 
       line buffered. 
       ....
       The standard error stream stderr is always unbuffered by default.
    

    【讨论】:

      【解决方案2】:

      这是因为puts 也在输出一个换行符,在可以确定为交互式的设备上,默认情况下会导致刷新(对于标准输出)(a)

      如果您最初的 printf 在末尾输出换行符,您应该会看到类似的效果:

      printf("hello, world\n");
      

      或者如果您在sleep() 调用之前fflush (stdout);

      C11的相关部分是7.21.3 Files,部分/7

      在程序启动时,预定义了三个文本流,不需要显式打开 — 标准输入(用于读取常规输入)、标准输出(用于写入 常规输出)和标准错误(用于写入诊断输出)。和最初一样 打开,标准错误流没有完全缓冲;标准输入和标准 当且仅当可以确定流不引用时,输出流才被完全缓冲 到交互式设备。

      这让人想起C89/90 4.9.3 Files 的日子:

      在程序启动时,预定义了三个文本流,不需要显式打开——标准输入(用于读取常规输入)、标准输出(用于写入常规输出)和标准错误(用于写入诊断输出)。打开时,标准错误流没有完全缓冲;当且仅当可以确定流不引用交互式设备时,标准输入和标准输出流才会被完全缓冲。


      (a):这不是相当那么简单。对于初学者来说,这是依赖于实现的,因为标准规定构成交互式设备的元素依赖于实现(behaviour 已指定,但未指定影响该行为的事物)。

      其次(根据here),标准仅在标准输出被完全缓冲时(当设备绝对不是交互式时)强制要求。对于交互式设备,它是无缓冲还是行缓冲是一个实现决定。

      【讨论】:

      • 可靠的答案。如果您提到标准自 C89 以来一直如此,我会给您+1,这将使您高于我的答案:)
      • 我绝对不能放弃一些廉价的代表。我只是碰巧有 c90 躺在硬盘上。现在我可以回家告诉妻子我“从不扔掉任何东西”的策略有好处——她不会对此感到高兴:-)
      【解决方案3】:

      据我了解,如果存在换行符\n,printf 将刷新流。 放,我不太确定。它可能取决于实现。

      您的睡眠时间刚好够不包含\n 的 printf 刷新流。

      我建议您在需要时使用fflush(stdout); 刷新流,然后您可以完全避免睡眠。

      【讨论】:

        猜你喜欢
        • 2011-01-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-23
        • 2015-01-06
        • 1970-01-01
        相关资源
        最近更新 更多