seekp和seekg在使用fstream时无法正常工作。

6
我在我的Debian x64 PC上运行C++程序时遇到了奇怪的行为。
我无法先读取文件,然后写入另一个值,再读取这些值。我阅读了很多信息,包括stackoverflow上的问题,并发现(也是通过实验)我需要同时更改seekp和seekg。我这样做了,一切正常... 直到我从流中读取东西。在读取操作之后,如果我将指针定位到文件开头,然后调用tellg(),tellp(),它们都返回“-1”。
测试代码:
void testFstreamSeekp() {
    fstream in("file", ios::in | ios::out);

    cout << "g: " << in.tellg() << endl;
    cout << "p: " << in.tellp() << endl;

    in.seekp(0, ios_base::end);

    cout << "endp g: " << in.tellg() << endl;
    cout << "endp p: " << in.tellp() << endl;

    in.seekp(0, ios_base::end);
    in.seekg(0, ios_base::end);

    cout << "end g: " << in.tellg() << endl;
    cout << "end p: " << in.tellp() << endl;

    in.seekp(0, ios_base::beg);
    in.seekg(0, ios_base::beg);

    cout << "beg g: " << in.tellg() << endl;
    cout << "beg p: " << in.tellp() << endl;

        // Everything is fine until here (that is tellp() == 0, tellg() == 0)
    int a, b;
    in >> a >> b;
    cout << "a: " << a << endl << "b: " << b << endl;

        // tellg() == -1, tellp() == -1 ?????????!!!!!!!!!!
    cout << "read g: " << in.tellg() << endl;
    cout << "read p: " << in.tellp() << endl;

    in.seekp(0, ios_base::beg);
    in.seekg(0, ios_base::beg);

        // tellg() == -1, tellp() == -1 ?????????!!!!!!!!!!
    cout << "beg g: " << in.tellg() << endl;
    cout << "beg p: " << in.tellp() << endl;
}

有人能告诉我发生了什么事情,以及我该怎么做才能解决这个问题吗?

1
如果流处于错误状态,则seekp()/seekg()将无法工作。你的文件是怎样的,你是否已经检查它是否成功打开? - jrok
Jrok,为什么你没有把它作为一个答案发布?你解决了我的问题,谢谢。读取数据后,fstream处于eof()状态。我已经清除了该流(in.clear()),现在它像魅力一样工作。 - Arks
相关链接:https://dev59.com/L2Yq5IYBdhLWcg3woCC7 - Andrew
1个回答

5
对于 `fstream` (`std::basic_filebuf`),单个文件位置可以通过 `seekp()` 和 `seekg()` 同时移动。
无法独立地跟踪 `put` 和 `get` 位置。
类模板 `std::basic_filebuf` 拥有一个单一的文件位置。
§ 27.9.1.1:
1. 类 basic_filebuf 将输入序列和输出序列与文件关联起来。 2. 对于由 class basic_filebuf 的对象控制的读取和写入序列的限制与使用标准 C 库文件进行读取和写入的限制相同。 3. 特别地: - 如果文件未打开以供读取,则无法读取输入序列。 - 如果文件未打开以供写入,则无法写入输出序列。 - 为输入序列和输出序列维护共同的文件位置。

这正是我所说的“我需要同时更改seekp和seekg”的意思。 - Arks
无论如何,POW,现在我明白我需要只使用一个函数(任意一个)来移动两个指针。 - Arks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接