首页 > 其他 > 详细

流随机访问

时间:2020-03-03 21:47:53      阅读:79      评论:0      收藏:0      [点我收藏+]

各种流类型通常都支持对流中数据的随机访问。但绝大多数系统中绑定到 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;
}

test.txt 原来的内容:

abcd
efj
hi
j

修改后的内容:

abcd
efj
hi
j
5 9 12 14

流随机访问

原文:https://www.cnblogs.com/xiaojianliu/p/12404832.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!