为什么printf()在睡眠前没有打印任何东西()?

时间:2008-12-03 18:42:34

标签: c stdout buffering

我正在和Kernighan和Ritchie的书学习C;我在第四章的基础知识(函数)。前几天我对sleep()函数感到好奇,所以试图像这样使用它:

#include <stdio.h>
#include <unistd.h>

int main(void)
{
  printf(" I like cows.");
  sleep(5);
  return 0;
}

问题是程序的输出,它看起来先是sleep()然后是printf(),换句话说,它会等待五秒然后打印字符串。所以我想,也许程序到sleep()这么快就不会让printf()按照我的意愿完成他的工作,即打印字符串然后再睡觉。

如何显示字符串然后让程序进入睡眠状态? 编译器是OpenBSD 4.3中的GCC 3.3.5(propolice)。

PS我不知道你如何正确地放置预处理器线。

4 个答案:

答案 0 :(得分:33)

printf()写入stdout(默认输出流),通常是行缓冲的。调用时间sleep时不会刷新缓冲区,因此当程序退出所有流时会自动刷新,这就是为什么它在退出之前打印的原因。打印换行符通常会导致流被刷新,或者您可以使用fflush函数:

int main(void)
{
  printf(" I like cows.\n");
  sleep(5);
  return 0;
}

或:

int main(void)
{
  printf(" I like cows.");
  fflush(stdout);
  sleep(5);
  return 0;
}

如果要打印到非缓冲行的流,如果重定向stdout或者您正在写入文件,可能就是这样,只是打印换行可能不起作用。在这种情况下,如果您希望立即写入数据,则应使用fflush

答案 1 :(得分:3)

你的问题是printf(以及使用stdio库写入stdout(标准输出)的任何其他内容)被缓冲 - 如果它进入控制台则行缓冲,如果它转到文件则缓冲大小。如果您在fflush(stdout);之后执行printf,它会执行您想要的操作。您可以尝试在字符串中添加换行符('\ n'),只要不将标准输出重定向到文件,这就行了。

我不是100%肯定,但我认为stderr没有缓冲,这可能会导致混淆,因为您可能会在输出之前输出stderr之前看到输出stdout }}

答案 2 :(得分:3)

缓冲意味着所有输出都存储在一个地方(称为缓冲区),并在其中存在一定数量的数据后输出。这样做是出于效率原因。

一些(大多数?)实现在写入控制台的换行符后清除缓冲区,因此您也可以尝试

printf(" I like cows.\n");

而不是调用fflush()

答案 3 :(得分:0)

我实现了如下的时间相遇;

for (int i = 1; i <= 60; i++) {
    printf("%02d", i);
    fflush(stdout);
    sleep(1);
    printf("\b\b");
}