获得和设置流指针--进行读取写入操作

/*
题目描述
(1)向文件test.txt中输出字符串,然后从中读取显示在屏幕
(2)对文件test.txt的字符串进行处理,通过写指针定位来完成原先文件中数据的重写


用到的关于输入输出流相关的知识   
   
 read( )函数
    从流中读取字符串的成员函数read
    该成员函数一般形式是:read(char* pch, int nCount)
    从输入流中读取nCount个字符。当输入流中的字符数小于nCount时,结束读取。经常使用read函数读取二进制数据。

 write( )函数    
    成员函数write()输出一串字符。
    该成员函数一般形式是:write(char* pch, int nCount)
   其中,pch是指向字符数组的指针; nCount指明从第一个参数中复制输出字符的个数。

文件的随机读写
(1)输出流随机访问函数
    输出流随机访问函数有seekp和tellp。
(2)输入流随机访问函数
    输入流随机访问函数有seekg和tellg。


获得和设置流指针(get and put stream pointers)
所有输入/输出流对象(i/o streams objects)都有至少一个流指针:
ifstream, 类似istream, 有一个被称为get pointer的指针,指向下一个将被读取的元素。
ofstream, 类似 ostream, 有一个指针 put pointer ,指向写入下一个元素的位置。
fstream, 类似 iostream, 同时继承了get 和 put
我们可以通过使用以下成员函数来读出或配置这些指向流中读写位置的流指针:

 tellg() 和 tellp()
这两个成员函数不用传入参数,返回pos_type 类型的值(根据ANSI-C++ 标准) ,就是一个整数,代表当前get 流指针的位置 (用tellg) 或 put 流指针的位置(用tellp).

 seekg() 和seekp()
这对函数分别用来改变流指针get 和put的位置。两个函数都被重载为两种不同的原型:
seekg ( pos_type position );
seekp ( pos_type position );

使用这个原型,流指针被改变为指向从文件开始计算的一个绝对位置。要求传入的参数类型与函数 tellg 和tellp 的返回值类型相同。

seekg ( off_type offset, seekdir direction );
seekp ( off_type offset, seekdir direction );

使用这个原型可以指定由参数direction决定的一个具体的指针开始计算的一个位移(offset)。它可以是:
ios::beg    从流开始位置计算的位移
ios::cur    从流指针当前位置开始计算的位移
ios::end    从流末尾处开始计算的位移

流指针 get 和 put 的值对文本文件(text file)和二进制文件(binary file)的计算方法都是不同的,因为文本模式的文件中某些特殊字符可能被修改。
由于这个原因,建议对以文本文件模式打开的文件总是使用seekg 和 seekp的第一种原型,而且不要对tellg 或 tellp 的返回值进行修改。
对二进制文件,你可以任意使用这些函数,应该不会有任何意外的行为产生。

*/

#include <fstream>
#include <iostream>
#include <cstring>
using namespace std;
int main ()
{
    long pos;//存储写指针位置(字节)

    char array[100]; //字符数组用来存放从文件中读取的字符串

    ofstream outfile; //建立输出文件流对象

    ifstream infile;  //建立输入文件流对象

    outfile.open ("test.txt"); //将输出流对象与test.txt文件关联

    infile.open ("test.txt");  //将输入流对象与test.txt文件关联

    if(!outfile&&!infile)
    {
        cout<<"file error!";
        exit(1);
    }

    cout<<"开始写入时,写指针位置为:"<<outfile.tellp()<<endl; 

    //outfile.write ("This is an apple.",sizeof("This is an apple.")-1); //参见输出流的write方法,向文件test.txt中输出字符串
    outfile.write ("This is an apple.",strlen("This is an apple.")); //参见输出流的write方法,向文件test.txt中输出字符串

    pos=outfile.tellp();//获取写入字符串后,写指针位置(与文件开始之间的字节数)
    
    cout<<"写入后,写指针位置为:"<<pos<<endl;   

    cout<<"开始读入时,读指针位置为:"<<infile.tellg()<<endl;

    infile.getline(array,pos+1); //将test.txt读取的内容存入数组array中

    cout<<"读入后,读指针位置为:"<<infile.tellg()<<endl;

    cout<<array<<endl;

    outfile.seekp (pos-8);//将写指针从当前位置向后移动(文件开头位置)8个字节

    pos=outfile.tellp();//获取写指针移动后,写指针位置(与文件开始之间的字节数)

    cout<<"将当前指针向前移动8个字节后,写指针位置为:"<<outfile.tellp()<<endl;

    outfile.write (" sam",sizeof(" sam")-1); //在从当前写指针位置开始写入字符串

    pos=outfile.tellp();//获取再次写入后,写指针位置(与文件开始之间的字节数)

    cout<<"再此写入后,写指针位置为:"<<pos<<endl;

    infile.seekg(0,ios::beg); //读指针定位到文件开头

    cout<<"重新从文件开头读入时,读指针位置为:"<<infile.tellg()<<endl;
    
    outfile.seekp(0,ios::end); //文件的写指针定位到文件最后

    pos=outfile.tellp();//获取写指针位置(与文件开始之间的字节数)

    cout<<"将写指针定位到文件最后位置为:"<<pos<<endl;
   
    infile.sync();//清除缓冲区
    infile.clear();//清除错误状态,在这个程序里,两个必须一起用,否则  达不到效果
    //以上两条语句非常重要,如果去掉,就读不进来了

    infile.getline(array,pos+1); //将test.txt读取的内容存入数组array中

    cout<<"读入后,读指针位置为:"<<infile.tellg()<<endl; 

    cout<<array<<endl;

    outfile.close(); //关闭文件

    infile.close(); //关闭文件

    return 0;
}

原文地址:https://www.cnblogs.com/beautiful-code/p/5239381.html