我正在阅读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();
}
正如您在上方看到的,输入和输出文件流对象in
和out
使用相同的文件,因此输出打开文件“ data.txt”并向其中写入一些行,但保存它,输入流将尝试读取此未保存文件的内容。
如果我将输入流对象in
绑定到out
,则可以正确获取内容。这是否意味着in
强制out
被刷新?
如果我在in.tie(&out)
行中注释掉了,那我使用的不是内容吗?
请向我解释一下它的工作原理。预先谢谢你。
答案 0 :(得分:6)
关于缓冲I / O的事情是,您永远无法真正确定何时将缓冲区的内容刷新到外部序列。 iostream对象的内部缓冲区的大小是由实现定义的,它们可以决定在关闭或销毁流之前的任何时候刷新缓冲区(或不刷新缓冲区)。只有在关闭流(通过显式调用close()
或生命周期结束)后才需要写入外部序列的流。这意味着输出操作 可以立即写入外部文件,也可以等待直到有更多内容流到缓冲区中。
您可以通过调用flush()
方法显式刷新流,但是当您像std::cin
和std::cout
那样在输入和输出之间切换时,执行{{1 }}在每个输入操作之前(如果之前有写操作)。这是“绑定”流的来源。当您绑定输出流时,调用std::cout.flush()
(在您的情况下为tie()
,通常为in
)中的流将调用{{1}在绑定流上执行的每个I / O操作之前。这样可以使两个流保持同步。
因此直接回答您的问题:
如果我将输入流对象
std::cin
与flush()
绑定在一起,则可以正确获取内容。这是否意味着in
强制out
被刷新了?
是的
如果我在
in
行中注释掉了,那我不使用out
得到内容吗?
这取决于流如何管理缓冲区。执行输出的流可以立即执行写操作,或者可以在决定写操作之前等待缓冲区被进一步填充,或者可以等待其生命周期结束。此决定在iostream实现之间有所不同。