You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何代码执行结束时tellg()返回-1?

为什么代码执行结束时tellg()返回-1?

嘿,这个问题其实和C++文件流的状态管理直接相关,我来一步步给你拆解清楚:

核心原因:流处于错误状态时tellg()会返回-1

你的代码里循环条件是while (obj),这个条件本质是检查文件流的状态是否有效。当循环执行到最后一次obj>>ch时:

  • 此时文件已经读到了末尾,>>操作符尝试读取文件结束标记,会触发流的eofbit(文件结束位),同时流的状态会变成失效(布尔值为false)。
  • 循环因此退出,但这时候文件流仍然处于错误状态,根据C++标准,此时调用tellg()会返回pos_type(-1)(也就是你看到的-1),用来表示操作失败。

顺便解释下输出里的“跳号”(比如从5到7)

你输出里的指针位置跳过了6,这是因为>>操作符默认会跳过空白字符(空格、换行、制表符等)。如果你的today.txt里位置6是空格或者换行,obj>>ch会直接跳过它,指针跳到下一个非空白字符的位置,所以输出里看不到6。

怎么获取最后有效的指针位置?

如果你想拿到文件最后一个有效字符的位置,或者文件末尾的真实位置,可以这么修改代码:

#include<iostream>
#include<fstream>
using namespace std;

int main() {
    system("cls");
    fstream obj;
    obj.open("today.txt", ios::in);
    char ch;
    streampos last_valid_pos = 0; // 记录每次成功读取后的位置

    // 先尝试读取,读取成功再进入循环
    while (obj >> ch) {
        last_valid_pos = obj.tellg();
        cout << endl << "file pointer at :" << last_valid_pos;
    }

    // 检查流失效的原因是到达文件末尾
    if (obj.eof()) {
        cout << endl << "End of file reached. Last valid position: " << last_valid_pos;
    }

    // 如果想直接获取文件末尾的位置,需要先重置流状态
    obj.clear(); // 清除流的错误标记
    obj.seekg(0, ios::end); // 跳转到文件末尾
    cout << endl << "Total file size (position at end): " << obj.tellg();

    return 0;
}

这里的关键细节:

  1. 用while (obj >> ch)替代原循环,确保只有读取成功时才执行循环体。
  2. 每次成功读取后记录指针位置,这样即使流最后失效,也能拿到最后有效的位置。
  3. 如果要在流失效后继续操作(比如跳转到末尾),必须先调用obj.clear()重置流的错误状态,否则所有操作都会失败。

内容的提问来源于stack exchange,提问作者Mohd Sarim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 19:22:33