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;

由于您的流是一个文件流,您可以寻找它回到开头以从头开始(这将固有地对其底层缓冲区执行相同的操作)。