ifstreams 和 rdbuf() 的奇怪行为
Weird behavior with ifstreams and rdbuf()
我注意到在 ifstream
上使用 .rdbuf()
似乎以某种方式改变了它。下面的代码应该能说明问题。
#include <fstream>
#include <iostream>
using namespace std;
int main(int argc, const char * argv[]) {
ifstream ifs("Sample.csv");
cout << "Reading buffer: " << endl;
cout << ifs.rdbuf(); // Outputs buffer as expected
cout << "Reading buffer again: " << endl;
cout << ifs.rdbuf(); // Returns nothing
return 0;
}
这让我感到困扰的原因是我目前正在尝试使用 ofstream ofs; ofs << ifs.rdbuf()
将一个文本文件的内容复制到另一个文本文件中。这工作正常,但使用 getline(ifs, str)
从 ifs
读取失败,实际上 "breaking" 流。
ifs.rdbuf()
returns 指向 ifs
对应的流缓冲区对象的指针。通过 <<
重载将其发送到 std::cout
从流中提取信息,直到达到缓冲区的末尾 (eof
)。再次调用 .rdbuf()
returns "nothing" 因为缓冲区末尾没有任何内容可读。通过调用 ifs.seekg (0);
.
将缓冲区查找位置显式重置为零
这不是特别的"weird";这与您每天看到的流行为相同。 rdbuf
不像 std::stringstream::str()
也不是魔法 — 它是一个指向缓冲区的指针,您的 cout
然后从中读取就像您自己从原始流中读取一样:
std::stringstream ss("1");
int x;
if (ss >> x)
cout << x;
if (ss >> x) // doesn't work a second time; "1" is already extracted
cout << x;
由于您的流是一个文件流,您可以寻找它回到开头以从头开始(这将固有地对其底层缓冲区执行相同的操作)。
我注意到在 ifstream
上使用 .rdbuf()
似乎以某种方式改变了它。下面的代码应该能说明问题。
#include <fstream>
#include <iostream>
using namespace std;
int main(int argc, const char * argv[]) {
ifstream ifs("Sample.csv");
cout << "Reading buffer: " << endl;
cout << ifs.rdbuf(); // Outputs buffer as expected
cout << "Reading buffer again: " << endl;
cout << ifs.rdbuf(); // Returns nothing
return 0;
}
这让我感到困扰的原因是我目前正在尝试使用 ofstream ofs; ofs << ifs.rdbuf()
将一个文本文件的内容复制到另一个文本文件中。这工作正常,但使用 getline(ifs, str)
从 ifs
读取失败,实际上 "breaking" 流。
ifs.rdbuf()
returns 指向 ifs
对应的流缓冲区对象的指针。通过 <<
重载将其发送到 std::cout
从流中提取信息,直到达到缓冲区的末尾 (eof
)。再次调用 .rdbuf()
returns "nothing" 因为缓冲区末尾没有任何内容可读。通过调用 ifs.seekg (0);
.
这不是特别的"weird";这与您每天看到的流行为相同。 rdbuf
不像 std::stringstream::str()
也不是魔法 — 它是一个指向缓冲区的指针,您的 cout
然后从中读取就像您自己从原始流中读取一样:
std::stringstream ss("1");
int x;
if (ss >> x)
cout << x;
if (ss >> x) // doesn't work a second time; "1" is already extracted
cout << x;
由于您的流是一个文件流,您可以寻找它回到开头以从头开始(这将固有地对其底层缓冲区执行相同的操作)。