7

我想知道使用 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!);
4

3 回答 3

10

这是因为缓冲 - 默认情况下,标准输出缓冲到每个新行。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.
于 2013-02-04T04:13:21.627 回答
9

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

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

printf("hello, world\n");

或者如果你fflush (stdout);sleep()打电话之前。

的相关部分C117.21.3 Files,部分/7

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

这可以追溯到C89/90 4.9.3 Files

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


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

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

于 2013-02-04T04:12:32.990 回答
0

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

您的睡眠时间足以让 printf 不包含 a\n来刷新流。

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

于 2013-02-04T04:12:46.120 回答