c++中cout缓冲区和endl的结构

structure of cout buffer and endl in c++

本文关键字:endl 结构 缓冲区 cout c++      更新时间:2023-10-16

我是C++的新手,学习C++ Primer的书。在第一章中,作者讨论了iostreamcoutendl的缓冲区。我不能很好地理解。我这里有两个代码示例。

#include<iostream>
int v1;
int main()
{
    std::cout<<"First Cout!";
    std::cin>>v1;
    std::cout<<"Second Cout!"<<std::endl;
    std::cout<<"Third Cout!n";
    return 0;
}

我想知道每一行执行后cout缓冲区的状态。

流包含一个内存缓冲区,在将数据刷新到最终目的地(在本例中为输出控制台)之前,会在其中写入数据,因为刷新可能是一项昂贵的操作。

在某些情况下,缓冲区可能会自动刷新:当流关闭时,或者如果有大量缓冲数据,或者如果流被配置为在每行之后刷新,就像std::cerr一样。

有时您需要手动刷新,例如,确保用户看到您写入std::cout的内容。这可以通过两种方式实现:

  • 调用流上的flush()成员函数
  • 将CCD_ 10操纵器流式传输到流中

std::endl操纵器做两件事:

  • 插入一个新的行字符(或字符序列),相当于<< 'n';那么
  • 刷新流,相当于<< std::flush(它反过来调用流的flush()成员函数)

这对于将短消息写入控制台非常有用;但应该谨慎使用,因为当产生大量输出时,它会对性能产生相当大的影响。

更复杂的是,一个流可以绑定到另一个流,因此在访问另一个之前先刷新一个流。在这种情况下,coutcin绑定,这就是为什么在从cin读取之前会看到第一个输出,即使没有显式刷新。

最后,包括cout在内的所有标准流都会在程序结束时自动刷新(特别是当std::ios_base::Init的全局实例被销毁时;但这是一个您不需要知道的细节)

在第一行之后,输出在缓冲区中,所以您不会在终端中看到它。

在第二行之后,endl将刷新缓冲区,因此您现在将在终端输出中看到第1行和第2行。

在第三行之后,输出在缓冲区中,直到程序退出,您才会在终端中看到它。

编辑:

当您在第1行和第2行之间放置cin时,它会导致cout被刷新。参见:std::cin

cin被绑定到标准输出流cout(请参见ios::tie),这表示在对cin执行每个i/o操作之前,cout的缓冲区都被刷新(请参见ostream::flush)。

在第1行之后,cout只包含给定的字符串,没有换行符。在第二行之后,cout还包含一行结尾,文本显示在控制台窗口。在第三行之后,cout包含另一个字符串,该字符串包括不一定出现在控制台窗口的行结束。退出main后,将显示第3行的文本。

std::endl只是将EOL(行尾)符号添加到输出中。通常是这样,但不同的操作系统可能会有所不同。