文件的读写操作3

来源:互联网 发布:网络封包登入 编辑:程序博客网 时间:2024/04/29 09:49

最后,将为大家介绍文件的随机存取。文件的随机存取是指按照要求直接,而不是依次,移动到文件的任何位置。要实现文件的定位,C++提供了seekg和seekp两个函数。前者将输入指针定位到指定的文件位置,而后者将输出指针定位到制定的文件位置。实际上,由于fstream类使用的是缓冲区来存储中间数据,因此,指针指向的其实是缓冲区中的位置,而不是实际的文件位置。这两个函数都有如下的两个原型:

istream & seekg/seekp(streampos);//移动输入/输出指针到距离文件开头相应位置istream & seekg/seekp(streamoff,ios_base::seek_dir);//移动输入/输出指针到距离文件指定位置的相应位置

前者将相应指针定位到距离(以字节为单位)文件开头的相应位置。后者将文件定位到距离(以字节为单位)指定文件位置的相应位置。说是指定文件位置,其实seek_dir只有三个值:ios_base::beg,ios_base::cur,ios_base::end分别对应文件开头、当前和结尾位置。streamoff为相对于相应位置的偏移量。下面列出了seekg函数的几个例子,seekp函数也与之类似,其中fin为ifstream对象。

fin.seekg(5,ios_base::beg);//离文件开始5个字节距离位置fin.seekg(-2,ios_base::cur);//离当前位置向前2个字节距离位置fin.seekg(0,ios_base::end);//离文件结尾0个字节距离位置,即文件结尾fin.seekg(521);//离文件开始521个字节距离位置

为了给大家介绍些新东西,下文的例子中,特意使用了fstream对象,此对象继承了iostream类以及两个缓冲区,即输入和输出缓冲区,并能同步化这两个缓冲区的处理,使输入指针和输出指针能够在相应的缓冲区中协调的移动。

#include <iostream>#include <fstream>using namespace std;struct testStruct {char name[20];double scores;};inline void eatline(){while(cin.get()!='\n') continue;}//get rid of newlineint main(){const char* fileName = "1.txt";testStruct t;fstream finout(fileName,ios_base::in|ios_base::out|ios_base::binary);//二进制读写模式if (!finout.is_open()){cout<<"file open error!"<<endl;exit(EXIT_FAILURE);}for (int i=0;i<3;i++){cin.get(t.name,20);cin>>t.scores;eatline();//去掉换行符,否则换行符会一直保留在缓冲区中,使两个数据无法输入finout.write((char*)&t,sizeof(t));//写入文件}finout.seekg(0);//将输入指针移动到文件头。其实不是必须的,只是为了说明如何使用seekg。while (finout.read((char*)&t,sizeof(t)))//未到文件尾,读取文件{cout<<t.name<<": "<<t.scores<<endl;} if (finout.eof())//到达文件尾后,程序将设置eofbit元素,使用clear重置流状态,使程序可以再次访问程序 finout.clear();int n;cout<<"Enter the number you wish to change: "<<endl;cin>>n;eatline();//去掉换行符streampos pos = (n-1) * sizeof(t);//使其从1开始计数finout.seekp(pos);//将输出指针移动到指定位置finout.read((char*)&t,sizeof(t));//读取当前位置内容finout.clear();//清空缓冲区cout<<"Your selection: "<<endl;cout<<t.name<<": "<<t.scores<<endl;cout<<"Enter the testStruct data: "<<endl;cin.get(t.name,20);eatline();//去掉换行符cin>>t.scores;eatline();//去掉换行符finout.seekp(pos);//将输出指针移动到指定位置finout.write((char*)&t,sizeof(t));//写入finout.seekg(0);//将输入指针移动到文件起始位置while (finout.read((char*)&t,sizeof(t)))//未到文件尾{cout<<t.name<<": "<<t.scores<<endl;}return 0;}

运行结果如下:


存入的二进制文件如下:


说明:关于程序上面的注释中已有详细说明,在此不再赘述。大家要注意以下两点:

1、cin和get会将换行符留在缓冲区,要注意其对下文输入的影响。

2、当程序读取并显示整个文件后,将会对eofbit进行设置,程序将会禁止对文件做进一步的读写。应使用clear重置流状态,使程序可以在此访问该文件。

本人才疏学浅,若有错误,欢迎指正,不胜感激。

0 0
原创粉丝点击