为什么cout立即输出?

时间:2017-12-18 17:11:10

标签: c++ io output buffer cout

cout是一个缓冲流。这意味着数据将被写入缓冲区,并在刷新流,程序终止或缓冲区完全填满时打印。

我制作了一个小程序来测试它是如何工作的,但我不明白为什么它会在满足上述任何条件之前打印出来。

#include <iostream>
#include <ctime>
using namespace std;

int main()
{
    cout << "Test";
    float secs = 5;
    clock_t delay = secs * CLOCKS_PER_SEC;
    clock_t start = clock();
    while (clock() - start < delay) { }
    return 0;
}

运行时,在循环开始之前输出“Test”。

为什么在程序终止之前我的输出没有缓冲?

2 个答案:

答案 0 :(得分:4)

here进行了很好的讨论。

从其中一个答案:

  

每个C ++流都使用关联的流缓冲区对象来执行缓冲。

     

构造std::cout时,它使用与stdout中声明的对象<cstdio>关联的流缓冲区。   默认情况下,std::cout上的操作可以与<cstdio>std::printf()输出函数自由混合。

     

实际上,同步通常意味着标准的iostream对象和标准的stdio对象共享一个缓冲区。 - 是

     

如果调用std::ios_base::sync_with_stdio(false)(在标准流上的任何输入或输出操作之前),标准C ++流独立于标准C流运行(即,它们切换到它们自己的独立流缓冲区)。

有关详情,请参阅cppreference上的sync_with_stdio功能参考页。

从该页面开始,功能......

  

设置在每次输入/输出操作后标准C ++流是否与标准C流同步。

     

...实际上,这意味着同步的C ++流是无缓冲的,并且C ++流上的每个I / O操作都会立即应用于相应的C流缓冲区。这使得可以自由地混合C ++和C I / O.

但是,请注意在已经读取或写入之后调用此函数:

  

如果在标准流上发生I / O后调用此函数,则行为是实现定义的:实现范围从无效到销毁读取缓冲区。

答案 1 :(得分:2)

还有另一个很棒的对话here。这似乎与scohe001提到的一些事情有关,但是有点不同,所以我会把它放在它自己的答案中。

与上述答案相关的是该论坛上的this帖子,其中讨论了如何根据其他周围代码刷新缓冲区。 Std :: cout函数与其他流函数绑定,而正常的c库函数与scohe001相同。因此,如果被调用的东西被绑定,它的缓冲区将在继续之前刷新。

您是在Linux上使用gcc编译它,还是在某些Windows环境中运行它?上面该论坛的帖子here讨论了操作系统特定的功能,而来自windows的sleep()可能会导致缓冲区清空。否则,正常的gcc编译的c ++代码不会使用sleep()打印缓冲区,只要它没有遇到任何其他代码在继续之前刷新缓冲区。

这些帖子涵盖了很多信息,所以我不会在这里复制并粘贴它,所以请原谅我stackoverflow众神。

我希望这些信息有所帮助!