seekp控制写指针、seekg控制读指针,二者完全独立;必须用binary模式、调用前clear()清状态、偏移量为字节单位,切换读写方向前需flush或sync以保证缓冲区同步。

seekp 和 seekg 的基本行为差异
seekp 控制输出流(写)的文件指针位置,seekg 控制输入流(读)的文件指针位置。它们**不是共享同一个指针**——即使你用 fstream 同时打开读写,内部仍维护两个独立位置。这意味着调用 seekp(100) 不会改变 seekg 当前的位置,反之亦然。
常见错误是以为“我刚 seekg 到中间读了点数据,接下来 write 就会自动从那里开始”,其实不会——必须显式调用 seekp 才能定位写入点。
使用 seekg/seekp 前必须检查流状态
这两个函数本身不抛异常,失败时只设置 failbit,且**不会自动清空缓冲区或刷新底层 I/O 缓冲**。如果之前有未完成的读/写操作(比如 read() 遇 EOF 或 write() 被截断),后续 seekg 可能直接返回失败。
- 调用前先确保
good()为 true,或至少!fail() && !bad() - 若刚执行过读/写,建议加
clear()清除可能残留的状态位 - 对磁盘文件,
seekg在eof()为 true 时大概率失败,需先clear()
示例:
std::fstream fs("data.bin", std::ios::in | std::ios::out | std::ios::binary);
fs.seekg(0, std::ios::end);
if (fs.fail()) {
fs.clear(); // 必须加这一行,否则 seekg(0) 可能继续失败
}
fs.seekg(0); // 现在才安全
偏移量参数和 whence 的实际含义
seekg(off, dir) 和 seekp(off, dir) 中的 off 是 std::streamoff 类型(通常是 long long),dir 必须是 std::ios::beg、std::ios::cur 或 std::ios::end 三者之一。注意:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
立即学习“C++免费学习笔记(深入)”;
-
std::ios::end表示从文件末尾算起,off为负数才有效(如seekg(-4, std::ios::end)定位到倒数第 4 字节) - 二进制模式下,偏移量单位是字节;文本模式下行为未定义(不同平台换行符处理不同),所以**必须用
std::ios::binary** - 如果
off超出当前文件长度(比如seekg(1000, std::ios::beg)但文件只有 200 字节),不会报错,但后续read()会立即返回 0 字节
seekg/seekp 后的读写必须考虑缓冲区同步
标准库实现通常带缓冲,seekg 或 seekp 并不保证立刻刷新底层文件句柄位置。尤其在混合读写场景中,容易出现“写入没生效”或“读到旧数据”的问题。
- 若刚用
seekp定位并write(),紧接着要seekg读同一位置,建议在write()后加flush() - 若刚
seekg并read(),再seekp写,无需 flush,但要注意read()可能已把后续数据预读进缓冲区 - 最稳妥的方式:每次切换读/写方向前,都调用
sync()(fstream::sync(),非std::cout.sync_with_stdio())——它会尝试同步底层文件指针与缓冲区状态
这一步常被忽略,但正是随机读写出错的核心原因之一:你以为指针动了,其实缓冲区还卡在上一个位置。

















