aihot  2020-11-12 09:24:27  OpenCV |   查看评论   
15 << "i:" << setw(12) << i << '\n' 16 << "d:" << setw(12) << d << '\n' 17 << setfill(' ');

9,流的随机访问

不同的流类型一般支持对相关流中数据的随机访问。可以重新定位流,以便环绕跳过,首先读最后一行,再读第一行,以此类推。标准库提供一对函数来定位(seek)给定位置并告诉(tell)相关流中的当前位置。

9.1 seek和tell函数

seekg:重新定位输入流中的标记

tellg:返回输入流中标记的当前位置

seekp:重新定位输出流中的标记

tellp:返回输出流中标记的当前位置

逻辑上,只能在istream或者ifstream或者istringstream上使用g版本,并且只能在ostream类型或其派生类性ofstream或者ostringstream之上使用p版本。iostream对象,fstream或者stringstream对象对相关流既可以读也可以写,可以使用两个版本的任意版本。9.

9.2 只有一个标记

虽然标准库区分输入和输入而有两个版本,但它只在文件中维持一个标记——没有可区分的读标记和写标记。

只是试图在ifstream对象上调用tellp的时候,编译器将会给出错误提示。反之亦然。

使用既可以读又能写的fstream类型以及stringstream类型的时候,只有一个保存数据的缓冲区和一个表示缓冲器中当前位置的标记,标准库将g版本和p版本都映射到这个标记。

9.3 普通iostream对象一般不允许随机访问。

9.4 重新定位标记

seekg(new_position);  seekp (new_position);  seekg( offset, dir);  seekp( offset, dir);

第一个版本将当前位置切换到给定地点,第二个版本接受一个偏移量以及从何处计算偏移的指示器。

9.5 访问标记

tell函数返回的一个值,使用适当类的pos_type成员来保存。

10,一个实例

假定给定一个文件来读,我们将在文件的末尾写一个新行,改行包含了每一行开头的相对位置(程序不必写第一行的偏移量,因为它总是0)。例如给定下面的文件,

abcd

efg

hi

j

这段程序应产生修改过的文件如下:

abcd

efg

hi

j

5 9 12 14

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include <fstream>
#include <string>
 
using std::fstream;
using std::cerr;
using std::endl;
using std::ifstream;
using std::ofstream;
using std::string;
using std::getline;
using std::cout;
//使用命名空间std;
 
int main()
{
    fstream inOut("copyOut.txt",
        fstream::ate | fstream::in | fstream::out);            //用ate方式打开,会将文件的位置定位到文件末尾。
 
    if( !inOut )        {
        cerr << "unable to open file" <<endl;
        return EXIT_FAILURE;
    }
 
    inOut.seekg(-1,fstream::end);            //去最后一个字符
    if( inOut.peek() != 10)                    //如果文件的最后一个字符不是换行符,请添加它。
    {
        inOut.seekg(0,fstream::end);
        inOut.put('\n');
    }
 
    inOut.seekg(0,fstream::end);
    ifstream::pos_type endMark = inOut.tellg();        //记录最后的位置。
 
    inOut.seekg(0,fstream::beg);
 
    int cnt = 0;                        //累加器用于字节计数
    string line;                        //保持每行输入
 
    while( inOut && inOut.tellg() != endMark
        && getline(inOut , line)
        )
    {
        cnt += line.size() + 1;            // 添加1以计算新行
 
        ifstream::pos_type mark = inOut.tellg();
        inOut.seekp( 0, fstream::end);    //设置写标记结束
        inOut << cnt;
 
        if( mark != endMark) inOut << " ";
        inOut.seekg(mark);                //恢复读取位置
    }
    inOut.clear();                        //清除标志,以防我们遇到错误
    inOut.seekp(0 , fstream::end);        //寻求结束
    inOut << endl;                        //在文件末尾写一个换行符
 
    return 0;
}
 

除特别注明外,本站所有文章均为 赢咖4注册 原创,转载请注明出处来自C++的那些事:流与IO类

留言与评论(共有 0 条评论)
   
验证码:
[lianlun]1[/lianlun]