一个流是如何与另一个流联系在一起的?
How is a stream tied to another flushed?
我正在阅读 C++ Primer,第 5 版。在谈论冲洗流时,它说:
An output stream might be tied to another stream. In this case, the buffer of
the tied stream is flushed whenever the tied stream is read or written. By
default, cin and cerr are both tied to cout. Hence, reading cin or writing to
cerr flushes the buffer in 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)
行,那么我无法使用 in?
获取内容
请向我解释一下它是如何工作的。提前谢谢你。
关于缓冲 I/O 的事情是,您永远无法真正确定缓冲区的内容何时会刷新到外部序列。 iostream 对象的内部缓冲区大小为 implementation-defined,并且它们可以决定在流关闭或销毁之前的任何时刻刷新缓冲区(或不刷新缓冲区)。只有当流关闭时(通过显式调用 close()
或其生命周期结束时),流才需要写入外部序列。这意味着输出操作可以立即写入外部文件,或者它可以等到有更多内容流入缓冲区。
您可以通过调用 flush()
方法显式刷新流,但是当您像使用 std::cin
和 std::cout
那样在输入和输出之间切换时,这样做会变得乏味 std::cout.flush()
在每次输入操作之前(如果之前有写)。这就是 "tying" 流的用武之地。当您绑定输出流时,调用 tie()
的流(在您的情况下为 in
,通常为 std::cin
)调用 flush()
在绑定流上执行的每个 I/O 操作之前。这允许两个流保持同步。
所以直接回答你的问题:
If I tie the input stream object in
with out
then I get the content correctly. Does this mean in
forces out
to be flushed?
是的。
If I comment out the line in.tie(&out)
then I don't get the content using in
?
这取决于流如何管理缓冲区。执行输出的流可以立即执行写入,或者它可以等待其缓冲区被进一步填充后再决定写入,或者它可以等到其生命周期结束。此决定因 iostream 实现而异。
我正在阅读 C++ Primer,第 5 版。在谈论冲洗流时,它说:
An output stream might be tied to another stream. In this case, the buffer of the tied stream is flushed whenever the tied stream is read or written. By default, cin and cerr are both tied to cout. Hence, reading cin or writing to cerr flushes the buffer in 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)
行,那么我无法使用 in? 获取内容
请向我解释一下它是如何工作的。提前谢谢你。
关于缓冲 I/O 的事情是,您永远无法真正确定缓冲区的内容何时会刷新到外部序列。 iostream 对象的内部缓冲区大小为 implementation-defined,并且它们可以决定在流关闭或销毁之前的任何时刻刷新缓冲区(或不刷新缓冲区)。只有当流关闭时(通过显式调用 close()
或其生命周期结束时),流才需要写入外部序列。这意味着输出操作可以立即写入外部文件,或者它可以等到有更多内容流入缓冲区。
您可以通过调用 flush()
方法显式刷新流,但是当您像使用 std::cin
和 std::cout
那样在输入和输出之间切换时,这样做会变得乏味 std::cout.flush()
在每次输入操作之前(如果之前有写)。这就是 "tying" 流的用武之地。当您绑定输出流时,调用 tie()
的流(在您的情况下为 in
,通常为 std::cin
)调用 flush()
在绑定流上执行的每个 I/O 操作之前。这允许两个流保持同步。
所以直接回答你的问题:
If I tie the input stream object
in
without
then I get the content correctly. Does this meanin
forcesout
to be flushed?
是的。
If I comment out the line
in.tie(&out)
then I don't get the content usingin
?
这取决于流如何管理缓冲区。执行输出的流可以立即执行写入,或者它可以等待其缓冲区被进一步填充后再决定写入,或者它可以等到其生命周期结束。此决定因 iostream 实现而异。