22

我只是在用 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)。

4

4 回答 4

43

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如果您希望立即写入数据,则应该使用。

于 2008-12-03T18:46:22.743 回答
8

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

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

于 2008-12-03T18:45:06.380 回答
6

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

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

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

而不是调用 fflush()

于 2008-12-03T18:47:16.297 回答
1

我实现了时间相遇如下;

for (int i = 1; i <= 60; i++) {
    printf("%02d", i);
    fflush(stdout);
    sleep(1);
    printf("\b\b");
}
于 2018-12-20T00:15:45.957 回答