C++移动和获取文件读写指针(seekp、seekg、tellg、tellp)


以一
以一 2023-12-31 03:22:14 52610 赞同 0 反对 0
分类: 资源
在读写文件时,有时希望直接跳到文件中的某处开始读写,这就需要先将文件的读写指针指向该处,然后再进行读写。 ifstream 类和 fstream 类有 seekg 成员函数,可以设置文件读指针的位置; ofstream 类和 fstream 类有 seekp 成员函数,可以设置文件写指针的位置。

C++移动和获取文件读写指针(seekp、seekg、tellg、tellp)

 

在读写文件时,有时希望直接跳到文件中的某处开始读写,这就需要先将文件的读写指针指向该处,然后再进行读写。
  • ifstream 类和 fstream 类有 seekg 成员函数,可以设置文件读指针的位置;
  • ofstream 类和 fstream 类有 seekp 成员函数,可以设置文件写指针的位置。

所谓“位置”,就是指距离文件开头有多少个字节。文件开头的位置是 0。

这两个函数的原型如下:

ostream & seekp (int offset, int mode);
istream & seekg (int offset, int mode);

mode 代表文件读写指针的设置模式,有以下三种选项:
  • ios::beg:让文件读指针(或写指针)指向从文件开始向后的 offset 字节处。offset 等于 0 即代表文件开头。在此情况下,offset 只能是非负数。
  • ios::cur:在此情况下,offset 为负数则表示将读指针(或写指针)从当前位置朝文件开头方向移动 offset 字节,为正数则表示将读指针(或写指针)从当前位置朝文件尾部移动 offset字节,为 0 则不移动。
  • ios::end:让文件读指针(或写指针)指向从文件结尾往前的 |offset|(offset 的绝对值)字节处。在此情况下,offset 只能是 0 或者负数。

此外,我们还可以得到当前读写指针的具体位置:
  • ifstream 类和 fstream 类还有 tellg 成员函数,能够返回文件读指针的位置;
  • ofstream 类和 fstream 类还有 tellp 成员函数,能够返回文件写指针的位置。

这两个成员函数的原型如下:

int tellg();
int tellp();

要获取文件长度,可以用 seekg 函数将文件读指针定位到文件尾部,再用 tellg 函数获取文件读指针的位置,此位置即为文件长度。

例题:假设学生记录文件 students.dat 是按照姓名排好序的,编写程序,在 students.dat 文件中用折半查找的方法找到姓名为 Jack 的学生记录,并将其年龄改为 20(假设文件很大,无法全部读入内存)。程序如下:
  1. #include <iostream>
  2. #include <fstream>
  3. #include <cstring>
  4. using namespace std;
  5. class CStudent
  6. {
  7. public:
  8. char szName[20];
  9. int age;
  10. };
  11. int main()
  12. {
  13. CStudent s;
  14. fstream ioFile("students.dat", ios::in|ios::out);//用既读又写的方式打开
  15. if(!ioFile) {
  16. cout << "error" ;
  17. return 0;
  18. }
  19. ioFile.seekg(0,ios::end); //定位读指针到文件尾部,
  20. //以便用以后tellg 获取文件长度
  21. int L = 0,R; // L是折半查找范围内第一个记录的序号
  22. // R是折半查找范围内最后一个记录的序号
  23. R = ioFile.tellg() / sizeof(CStudent) - 1;
  24. //首次查找范围的最后一个记录的序号就是: 记录总数- 1
  25. do {
  26. int mid = (L + R)/2; //要用查找范围正中的记录和待查找的名字比对
  27. ioFile.seekg(mid *sizeof(CStudent),ios::beg); //定位到正中的记录
  28. ioFile.read((char *)&s, sizeof(s));
  29. int tmp = strcmp( s.szName,"Jack");
  30. if(tmp == 0) { //找到了
  31. s.age = 20;
  32. ioFile.seekp(mid*sizeof(CStudent),ios::beg);
  33. ioFile.write((char*)&s, sizeof(s));
  34. break;
  35. }
  36. else if (tmp > 0) //继续到前一半查找
  37. R = mid - 1 ;
  38. else //继续到后一半查找
  39. L = mid + 1;
  40. }while(L <= R);
  41. ioFile.close();
  42. return 0;
  43. }

如果您发现该资源为电子书等存在侵权的资源或对该资源描述不正确等,可点击“私信”按钮向作者进行反馈;如作者无回复可进行平台仲裁,我们会在第一时间进行处理!

评价 0 条
以一L0
粉丝 0 资源 1143 + 关注 私信
最近热门资源
银河麒麟桌面操作系统备份用户数据  124
统信桌面专业版【全盘安装UOS系统】介绍  119
银河麒麟桌面操作系统安装佳能打印机驱动方法  110
银河麒麟桌面操作系统 V10-SP1用户密码修改  104
最近下载排行榜
银河麒麟桌面操作系统备份用户数据 0
统信桌面专业版【全盘安装UOS系统】介绍 0
银河麒麟桌面操作系统安装佳能打印机驱动方法 0
银河麒麟桌面操作系统 V10-SP1用户密码修改 0
作者收入月榜
1

prtyaa 收益393.62元

2

zlj141319 收益218元

3

1843880570 收益214.2元

4

IT-feng 收益209.03元

5

风晓 收益208.24元

6

777 收益172.71元

7

Fhawking 收益106.6元

8

信创来了 收益105.84元

9

克里斯蒂亚诺诺 收益91.08元

10

技术-小陈 收益79.5元

请使用微信扫码

加入交流群

请使用微信扫一扫!