c++中cout缓冲区和endl的结构
structure of cout buffer and endl in c++
我是C++
的新手,学习C++ Primer
的书。在第一章中,作者讨论了iostream
、cout
和endl
的缓冲区。我不能很好地理解。我这里有两个代码示例。
#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()
成员函数)
这对于将短消息写入控制台非常有用;但应该谨慎使用,因为当产生大量输出时,它会对性能产生相当大的影响。
更复杂的是,一个流可以绑定到另一个流,因此在访问另一个之前先刷新一个流。在这种情况下,cout
与cin
绑定,这就是为什么在从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(行尾)符号添加到输出中。通常是这样,但不同的操作系统可能会有所不同。
- 如何循环打印顶点结构
- 通过方法访问结构
- 使用不带参数的函数访问结构元素
- 预处理器:插入结构名称中的前一个行号
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 孤立代码块在结构中引发异常
- 有什么方法可以遍历结构吗
- 如何在 C# 中映射双 C 结构指针?
- 如何在C++中使用结构生成映射
- 无法将结构注册为增强几何体3D点
- 多成员Constexpr结构初始化
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- C++将文本文件中的数据读取到结构数组中
- 如何重构类层次结构以避免菱形问题
- 如何在C++中序列化结构数据
- std::vector的包装器,使数组的结构看起来像结构的数组
- 没有为自己的结构调用列表推回方法
- 奇怪的结构&GCC&clang(void*返回类型)
- 在 c++ 中拥有一组结构的正确方法是什么?
- c++中cout缓冲区和endl的结构