【问题标题】:Why doesn't this code using printf and cout have the expected output?为什么这段使用 printf 和 cout 的代码没有预期的输出?
【发布时间】:2015-06-21 19:57:38
【问题描述】:

我有以下代码:

int main ()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);    

    for (int i = 0; i < 3; i++) {
        cout << i << " ";
        printf("%d ", i);
    }

    cout << endl;
    return 0;
}

这段代码的预期输出是:

0 0 1 1 2 2

但是,它会打印:

0 1 2
0 1 2

此问题发生在 GNU G++ 4.9.2 编译器中

【问题讨论】:

  • @KerrekSB 就是这样,我不想从你那里窃取答案。 printf 和 cout 使用在不同时间刷新的单独缓冲区。在上述代码的情况下,cout 很可能在行中被刷新,而 printf 在调用结束时被刷新。将 printf 中的空格替换为其他内容 (_),您会看到它。
  • 添加fflush(stdout)?
  • 这个问题没有多大意义;与 stdio 显式取消同步标准流后,您会问为什么它们的行为就好像它们已取消同步?
  • @T.C.如果您确切地知道发生了什么,这个问题就没有多大意义,我的意思是,对ios_base::sync_with_stdio(false) 的调用实际上做了什么。也许这条线只是为了提高使用 cin/cout 的 I/O 操作的性能
  • 你自己关掉了同步,问他们为什么不同步%)

标签: c++ compilation output


【解决方案1】:

对此的一种可能解释是coutprintf 使用单独的缓冲区。 cout 在使用endl 命令刷新终端屏幕或缓冲区已满(通常为 512 字节)时在终端屏幕上输出。

我不确定printf(如果我错了,请随时纠正我),但它也遵循类似的行为。所以会发生的是,在程序结束时,两个缓冲区都被刷新,所以你看到的输出就实现了。

我在我的机器(GCC 4.8.1)上运行了代码以及如下修改

cout << i << " . ";
printf("%d ", i);

我观察到的输出是0 1 2 0 . 1 . 2 .,这似乎表明在我的情况下 printf 首先刷新。我不知道它是设计使然(在标准中的某处提到),还是取决于上下文。

【讨论】:

  • 相当肯定 cout 也会刷新换行符,尽管大多数 istreams 不会。
  • @MooingDuck :根据我的阅读,cout 在输出到交互式设备(例如终端)时刷新换行符,但在写入文件时不刷新。
【解决方案2】:

默认情况下,C stdio 函数 printf 等和 C++ io 流是同步的,这意味着它们可以互换使用。在代码的开头,您已删除与 ios_base::sync_with_stdio(false) 的同步,不确定您的实际意图是否是编写此同步两个 io 库的 ios_base::sync_with_stdio(true)

【讨论】:

    【解决方案3】:

    试试这个

        cout << i << " " <<std::flush;
        printf("%d ", i);
        fflush(stdout);
    

    【讨论】:

      【解决方案4】:

      如果您希望输出 std::coutprintf 被同步,您需要使用:

      std::ios_base::sync_with_stdio(true);
      

      不是

      std::ios_base::sync_with_stdio(false);
      

      http://ideone.com/7sgH2I查看它。

      【讨论】:

        【解决方案5】:

        你可能会错过flush()std::coutprintf() 对此有不同的行为。 IO 缓冲区也应该同步。如果您将代码更改为

        int main () {
            ios_base::sync_with_stdio(true); // Synchronizing the IO buffers
                                             // must be enabled
            cin.tie(NULL);    
        
            for (int i = 0; i < 3; i++) {
                cout << i << " ";
                cout.flush(); // <<<<<<<<<<
                printf("%d ", i);
            }
        
            cout << endl;
            return 0;
        }
        

        它的行为应该符合您的预期。请参阅工作演示here

        【讨论】:

        • 它产生相同的输出
        • @ReynaldoAguilar 我已经修好了。
        猜你喜欢
        • 2011-01-23
        • 2019-11-14
        • 1970-01-01
        • 2018-07-20
        • 1970-01-01
        • 1970-01-01
        • 2015-07-03
        • 1970-01-01
        • 2016-04-20
        相关资源
        最近更新 更多