下面是在cpp preference网站上找到的代码。
#include <fstream>
#include <iomanip>
#include <iostream>
#include <string>
int main()
{
std::ofstream os("test.txt");
std::ifstream is("test.txt");
std::string value("0");
os << "Hello"; // clause 1
is >> value;// clause 2
std::cout << "Result before tie(): " << std::quoted(value) << "\n";
is.clear();
is.tie(&os);
is >> value;
std::cout << "Result after tie(): " << std::quoted(value) << "\n";
}
结果:
并列前的结果():“0”
并列后的结果():“你好”
问题:
我在第2条做了一个断点,注意到文件测试。txt未填充“hello”。
为什么?
谢谢
1条答案
按热度按时间oxf4rvwz1#
您对
os
的写入是buffered,不会立即刷新到磁盘。因此,从is
进行的第一次读取尝试不会“看到”数据。那么,为什么
tie()
调用可以解决这个问题呢?根据documentation ofbasic_ios::tie()
:绑定流是与流缓冲区(
rdbuf()
)控制的序列同步的输出流,即在*this
上的任何输入/输出操作之前,在绑定流上调用flush()
。所以在我们的例子中,对于
is.tie(&os)
调用,is
是“*this
”,os
是“tied stream
”。因此,该语句指示标准库在对is
进行每次输入操作之前自动调用os.flush()
。因此,在第二次读取
is
时,将数据写入磁盘的os.flush()
首先被标准库隐式调用,这使得输入流可以读取数据。您可以通过在子句1和2之间手动添加
os.flush()
(Godbolt)来获得相同的结果并在第一次读取时接收数据:但我应该注意,正如人们在评论中提到的那样,所有这些都很棘手,很容易导致难以掌握的代码。因此,通常应避免同时使用不同的句柄对同一文件进行阅读操作,除非绝对必要。