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

ate模式下seekp()后tellp()返回-1问题排查及代码修正

关于C++中seekp()和tellp()在ios::ate模式下的异常问题排查

最近在测试C++文件流的seekp()和tellp()函数时,碰到个让人困惑的问题:用ios::ate模式打开文件后,执行f2.seekp(10)再调用tellp(),返回值居然是-1。而且这个结果在Visual Studio和TDM GCC 4.9.2 64位编译器里完全一致,一开始我还以为是ate模式下seekp()有什么特殊限制,折腾了半天才发现是自己代码里的低级错误。

初始错误代码

/** 以ate模式打开,ios::in用于确保文件不被销毁 */
ofstream f2("h2.txt", ios::ate | ios::out | ios::in);
if (!f2) //0表示错误,也可使用f1.fail()
{
    // 打开失败
    cerr << "cannot open the file\n";
    exit(-1);
}
ios::pos_type currentPos = f2.tellp();
cout << "Initial Write Pointer Position = " << currentPos << endl;
// 写入数据,应写入文件末尾
f2 << 20;
currentPos = f2.tellp();
cout << "Write Pointer Position after write = " << currentPos << endl;
// 定位到指定位置,文件指针应相应改变
f2.seekp(10);
currentPos = f1.tellp(); // 此处存在错误,引用未定义的f1
cout << "Write Pointer Position after seek = " << currentPos << endl;
// 写入数据
f2 << "ABC";
currentPos = f2.tellp();
cout << "Final Write Pointer seek and write = " << currentPos << endl;
f2.close();

问题根源其实非常简单:调用tellp()时错误引用了未定义的f1,而非实际打开的文件流f2。f1从未被初始化过,调用它的成员函数自然会返回无效值-1,这跟seekp()本身的功能、ios::ate模式都没关系,纯粹是笔误导致的假异常。

修正后的完整代码

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

int main() {
    string file_name;
    int currentPos;
    cout << "Enter the file name: ";
    getline(cin, file_name);
    fstream f2(file_name, ios::ate | ios::out | ios::in);
    if (!f2) // 0表示错误,也可使用f2.fail()
    {
        // 打开失败
        cerr << "cannot open the file\n";
    }
    else {
        currentPos = f2.tellp();
        cout << "Initial Write Pointer Position = " << currentPos << endl;
        // 写入数据,应写入文件末尾
        f2 << 20;
        currentPos = f2.tellp();
        cout << "Write Pointer Position after write = " << currentPos << endl;
        // 定位到指定位置,文件指针应相应改变
        f2.seekp(10);
        currentPos = f2.tellp();
        cout << "Write Pointer Position after seek = " << currentPos << endl;
        // 写入数据
        f2 << "ABC";
        currentPos = f2.tellp();
        cout << "Final Write Pointer seek and write = " << currentPos << endl;
        f2.close();
    }
    return 0;
}

修正的关键点:

  • 将错误的f1.tellp()改为f2.tellp(),引用正确的文件流对象
  • 把错误提示里的f1.fail()修正为f2.fail(),保持代码一致性
  • 改用fstream替代ofstream(虽然ofstream加ios::in也能运行,但fstream更贴合读写两用的场景)
  • 增加了必要的头文件,同时支持用户输入文件名,让代码更通用

修正后再次运行,seekp(10)可以正常将写指针定位到第10个位置,tellp()也会返回预期的正确数值——这说明ios::ate模式下seekp()的功能完全正常,之前的异常只是代码笔误造成的乌龙。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:04:18