seekg/seekp调用后读写无变化的主因是流处于failbit/badbit错误状态,如文件未打开、已触发EOF或以ios::app模式打开(此时seekp被忽略);须先clear()清错并确保用ios::binary模式精确定位。

用 seekg 移动输入流指针、seekp 移动输出流指针,但必须确保流处于可定位状态(比如文件打开成功、未发生错误、且不是只读/只写限制导致的不可定位)。
为什么 seekg/seekp 调用后读写没变化?
最常见原因是流已进入失败状态(failbit 或 badbit),比如文件没打开、之前读取触发了 EOF、或以 ios::app 模式打开——这种模式下 seekp 会被忽略(C++ 标准强制要求)。
- 调用前务必检查:
if (file.good())或if (!file.fail() && !file.bad()) - 用
file.clear()清除错误标志(仅当确定可恢复时) -
ios::app下无法用seekp回退写入位置;改用ios::in | ios::out模式打开
seekg 和 seekp 的参数怎么选?
两者都接受两个参数:offset(偏移量)和 way(基准位置)。way 只能是 ios::beg、ios::cur 或 ios::end;offset 是 streamoff 类型(通常是 long long),正负都有意义。
-
file.seekg(10, ios::beg):跳到第 10 字节(从头开始,索引 0 起算) -
file.seekg(-5, ios::cur):当前位置往回退 5 字节(注意:不能退到文件开头之前) -
file.seekg(0, ios::end):跳到末尾,配合file.tellg()获取文件大小 - 对文本文件,用
seekg/seekp可能有未定义行为(尤其含换行符时),建议只在二进制模式(ios::binary)下精确移动
为什么 tellg/tellp 返回 -1?
tellg 和 tellp 在流不可定位或出错时返回 -1(即 streampos(-1))。这不是“位置为 -1”,而是明确的错误信号。
- 常见诱因:文件以
ios::ate打开后未做任何 I/O 就直接调用tellg(某些实现可能不支持) - 更稳妥的做法:先执行一次无副作用操作,如
file.peek()或file.get()再tellg - 二进制模式下
tellg返回值可直接用于后续seekg;文本模式下该值不应被假设为字节偏移
真正麻烦的是跨平台文本换行处理(\r\n vs \n)导致的 seekg 偏移错位——只要不用 ios::binary,就别指望指针移动是字节精确的。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











