seekg用于输入流(如ifstream),调整下一次读操作位置;seekp用于输出流(如ofstream),控制下一次写操作位置;二者不可混用,否则编译失败或行为未定义。

seekg 用于读取流(如 ifstream),seekp 用于写入流(如 ofstream);不能混用,否则编译报错或行为未定义。
seekg 只能用在输入流上
seekg 是 istream 的成员函数,因此只对 ifstream 和支持读的 fstream 有效。它调整的是「下一次读操作的起始位置」。
- 常见错误:对
ofstream调用seekg—— 编译失败,因为该类没有这个成员 - 典型场景:跳过文件头、随机读某一行、重读上一段内容
- 两个重载形式都可用:
seekg(pos)(绝对定位)或seekg(off, dir)(相对定位) - 配合
tellg()使用最稳妥,比如先记位置auto pos = file.tellg();,处理完再file.seekg(pos);
seekp 只能用在输出流上
seekp 是 ostream 的成员函数,只适用于 ofstream 和可写的 fstream。它控制的是「下一次写操作落笔的位置」。
- 常见错误:在只读打开的
ifstream上调用seekp—— 编译不通过 - 典型场景:覆盖写入某段内容、在文件末尾前插入数据(需先
seekp再write)、构建日志偏移索引 - 注意:如果用
ios::app模式打开文件,seekp通常无效,因为所有写操作强制追加到末尾 - 二进制写入时务必用
seekp配合write(),文本模式下用可能因换行符扩展导致位置偏移
fstream 中两者都能用,但得看打开模式
fstream 同时继承了 istream 和 ostream,所以 seekg 和 seekp 都存在 —— 但能否生效取决于实际打开方式。
- 用
ios::in | ios::out打开:两者都可用,读写指针独立维护 - 用
ios::in | ios::out | ios::binary打开:推荐,避免文本模式下的自动换行转换干扰定位 - 用
ios::out单独打开(默认含trunc):seekg会失败,因为没开启读权限;seekp有效,但文件可能被清空 - 容易忽略的点:
seekg和seekp修改的是各自方向的指针,不是共享一个位置;tellg()和tellp()返回值可能不同
真正容易出问题的地方在于:你以为在改同一个“文件指针”,其实读指针和写指针是分开的,尤其在混合读写时,不显式调用 seekg 或 seekp 就直接读/写,结果往往不是你预期的位置。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











