各种流类型通常都支持对流中数据的随机访问. 但绝大多数系统中绑定到 cin,cout,cerr,clog 的流不支持随机访问.
seek 和 tell 函数
函数 | 说明 |
---|---|
tellg | 返回输入流中标记的当前位置 |
tellp | 返回输出流中标记的当前位置 |
seekg(pos) | 在一个输入流中将标记重定位到给定的绝对地址 |
seekp(pos) | 在一个输出流中将标记重定位到给定的绝对地址 |
seekg(off,from) | 在一个输入流中将标记重定位到给定 from 的偏移量为 offset 的位置 |
seekp(off,from) | 在一个输出流中将标记重定位到给定 from 的偏移量为 offset 的位置 |
上面 from 的取值可以是:
beg, 偏移量相对于流开始位置.
cur, 偏移量相对于流当前位置.
end, 偏移量相对于流结尾位置.
注意:
g 版本用于读取的数据, 理论上来讲只能对 istream 和派生自 istream 的类型 ifstream 和 istringstream 使用 g 版本.
p 版本用于写入的数据, 理论上来讲对 ostream 和派生自 ostream 的类型 ofstream 和 ostringstream 使用 p 版本.
fstream 和 stringstream 既能读又能写, 因此这些类型既可以使用 g 版本也可以使用 p 版本.
只有一个标记
标记只有一个, 并不存在独立的读标记和独立的写标记.
重定位标记
pos 的类型是 pos_type, 表示一个文件位置.
offset 的类型是 off_type, 表示一个偏移量, 可以是正的也可以是负的, 表示向前, 向后移动.
- int main(void)
- {
- fstream inOut("test.txt", fstream::ate | fstream::in | fstream::out);
- if (!inOut)
- {
- cerr << "Unable to open file" << endl;
- return EXIT_FAILURE;
- }
- auto end_mark = inOut.tellg(); //@ ate 模式打开, 因此是文件末尾位置
- inOut.seekg(0, fstream::beg); //@ 重定位到文件首位置
- size_t cnt = 0;
- string line;
- while (inOut && inOut.tellg() != end_mark && getline(inOut, line))
- {
- cnt += line.size() + 1; //@ +1 表示换行符
- auto mark = inOut.tellg(); //@ 记录当前的读取位置
- inOut.seekp(0,fstream::end); //@ 写指针移动到文件尾
- inOut << cnt; //@ 写入累计长度
- if (mark != end_mark) inOut << " ";
- inOut.seekg(mark); //@ 恢复到读位置
- }
- inOut.seekp(0, fstream::end); //@ 定位到文件尾
- inOut << "\n"; //@ 在文件尾输出一个换行符
- return 0;
- }
- abcd
- efj
- hi
- j
- 5 9 12 14
来源: http://www.bubuko.com/infodetail-3445954.html