我正在阅读C ++ Primer,第5版。当谈论冲洗流时,它说:
输出流可能会绑定到另一个流。在这种情况下,每当读取或写入绑定流时,都会刷新绑定流的缓冲区。默认情况下,cin和cerr都与cout绑定在一起。因此,读取cin或写入cerr会冲洗cout中的缓冲区。
我试图通过一个例子来理解这一点:
int main() {
std::ofstream out("data.txt");
std::ifstream in("data.txt");
//in.tie(&out);// commenting this will print nothing
out << "Hello there!";
std::string str;
while (in >> str)
std::cout << str << " ";
out.close();
in.close();
}
Run Code Online (Sandbox Code Playgroud)
如您在上方看到的输入和输出文件流对象in
并out
使用相同的文件,因此输出一个打开文件“ data.txt”并向其中写入一些行,但不保存它,输入流尝试读取内容未保存文件的内容。
如果将输入流对象绑定到该对象in
,out
则可以正确获取内容。这是否意味着in
军队out
被刷新?
如果我注释掉该行,in.tie(&out)
那么我不会使用in来获取内容?
请在这里向我解释它是如何工作的。先感谢您。
关于缓冲I / O的事情是,您永远无法真正确定何时将缓冲区的内容刷新到外部序列。iostream对象的内部缓冲区的大小是实现定义的,它们可以决定在关闭或销毁流之前的任何时候刷新缓冲区(或不刷新缓冲区)。只有在关闭流时(通过显式调用close()
或其生命周期结束),才需要写入外部序列的流。这意味着输出操作可以立即写入外部文件,也可以等待直到有更多内容流式传输到缓冲区中。
您可以通过调用flush()
方法来显式刷新流,但是当您像std::cin
和一样在输入和输出之间切换时std::cout
,std::cout.flush()
在每次输入操作之前执行操作(如果在其之前进行了写入操作)将变得很繁琐。这就是“绑定”流的出现。绑定输出流时,调用的流tie()
(在您的情况下in
,通常是std::cin
)flush()
在绑定的流执行的每个I / O操作之前对其进行调用。这允许两个流保持同步。
因此,直接回答您的问题:
如果将输入流对象
in
与之绑定,out
则可以正确获取内容。这是否意味着in
军队out
被刷新?
是。
如果我注释掉该行,
in.tie(&out)
那么我不会使用in
?
这取决于流如何管理缓冲区。执行输出的流可以立即执行写操作,或者可以在决定写操作之前等待缓冲区被进一步填充,或者可以等待其生命周期结束。此决定在iostream实现之间有所不同。