ifstreams和rdbuf()的奇怪行为

时间:2016-08-06 19:55:32

标签: c++ c++11 fstream ifstream

我注意到在.rdbuf()上使用ifstream似乎会以某种方式改变它。以下代码应显示问题。

#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()将一个文本文件的内容复制到另一个文本文件中。这样可以正常工作,但是使用ifsgetline(ifs, str)进行阅读会失败,从而有效地破坏&#34;流。

2 个答案:

答案 0 :(得分:3)

这并不特别“怪异”。它与您每天看到的流行为相同。 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;

由于您的流是一个文件流,您可以寻找它回到开头从头开始(这本身就会对其底层缓冲区做同样的事情)。

答案 1 :(得分:2)

ifs.rdbuf()返回指向ifs对应的流缓冲区对象的指针。通过std::cout重载将其发送到<<会从流中提取信息,直到达到缓冲区的末尾(eof)。再次调用.rdbuf()会返回“nothing”,因为在缓冲区末尾没有任何内容可读。通过调用ifs.seekg (0);将缓冲区搜索位置显式重置为零。