【问题标题】:Streaming output to stdout, in-place status updates to stderr流式输出到标准输出,就地状态更新到标准错误
【发布时间】:2018-10-21 08:02:12
【问题描述】:

我有一个程序应该在stdout 上产生输出,在stderr 上产生瞬态状态信息。具有相似结果的程序可能包括 rsync 或 apt(尽管它们的输出非常复杂,以至于将其减少到我需要的基本要素是令人生畏的)。

这个程序似乎应该像描述的那样工作,但没有:

#include <stdio.h>
#include <limits.h>

void *work () {
  for (long i = 0; i < LONG_MAX; i++) {
    if (i % 100000000 == 0) {
      fprintf(stdout, "%ld\n", i);
    }
    fprintf(stderr, "\rrunning %ld", i);
  }

  return 0;
}

int main() {
  work(0);
  fprintf(stderr, "\ndone\n");
  return 0;
}

状态信息根据需要通过stderr 更新到位,但通过stdout 仅显示一行输出。如果stderr 状态fprintf 被删除,那么所有stdout 输出都会按预期显示。

这是怎么回事?

【问题讨论】:

  • 每次打印后尝试 fflush(stdout) 和 fflush(stderr)。
  • 那无济于事。 stdout默认是行缓冲的,输出到stdout后面有换行符,stderr默认是无缓冲的。

标签: c printf stdio


【解决方案1】:

这段代码是正确的(好吧,从 work() 返回的 void * 是错误的形式——void 会好得多)。

我怀疑问题只是你等待的时间不够长——迭代 100,000,000 次迭代需要时间,尤其是每次通过循环输出时(请记住——一旦你填满了输出,你就会阻塞标准输出缓冲区)。

我估计至少需要 3 分钟才能将第二个输出输出到 stdout。

【讨论】:

  • 点重新:形式,但我远离我的实际专业知识。 :-) 但是,不,如果您注释掉 stderr fprintf 行,您会很快看到结果,在我的笔记本电脑上约为 5 行/秒。
  • 这是有道理的——在你得到第二个写入 stdout 的数字之前,一直在花费 100,000,000 个数字到 stderr 的输出。
  • Re: form,你的声明的问题是 work() 被声明为返回一个指针,但你返回的是一个 int (C 编译器的特殊情况 0,所以你可以将它视为一个指针而不会得到一个错误;如果您将 return 0 更改为 return 1,它将无法编译)。因为您实际上并没有使用返回值,所以最好将例程声明为 void 而不是返回值。这个函数很简单,其实并不重要,但如果你继续写 C,总有一天你会很高兴得到一个编译错误,而不是需要调试。
  • 在该示例中,您对输出到 stderr 的时间是正确的。不幸的是,我认为这是一个最小的案例,证明了我在一个更大的程序中看到的失败。我会看看我能做些什么来更新问题以实际重现我看到的有问题的行为。
猜你喜欢
  • 2011-03-09
  • 1970-01-01
  • 2011-04-22
  • 2011-03-24
  • 1970-01-01
  • 1970-01-01
  • 2012-08-22
  • 1970-01-01
相关资源
最近更新 更多