当前位置: 首页 > news >正文

北大C++课后记录:文件读写的I/O流

前言

文件和平常用到的cincout流其实是一回事,可以将文件看作一个有限字符构成的顺序字符流,基于此,也可以像cincout读键盘数据那样对文件进行读写。


读写指针

  • 输入流的read指针
    在这里插入图片描述
  • 输出流的write指针
    在这里插入图片描述

注:这里的指针并不是普通的内存指针(*ptr),而是一种叫std::streampos类型的指针,是用于在文件流中定位文件位置的数据类型,可以类比成一个int型的数据。


文本文件读写demo

#include <iostream>
#include <fstream>
#include <algorithm>
#include <cstring>
#include <string.h>
#include <vector>
using namespace std;int main(){vector<int> v;ifstream srcFile("testin.txt", ios :: in);ofstream destFile("testout.txt", ios :: out);int t;while(srcFile >> t)v.push_back(t);sort(v.begin(), v.end());for(auto i : v)destFile << i << ' ';//不执行close的话数据还在内存(的缓冲区)里没被磁盘读走srcFile.close();destFile.close();return 0;
}
//testin.txt: 9 84 23 15 56 2 34 123 5 1
//testout.txt: 1 2 5 9 15 23 34 56 84 123 

二进制文件读写demo1

在这里插入图片描述
在这里插入图片描述

#include <iostream>
#include <fstream>
#include <algorithm>
#include <cstring>
#include <string.h>
#include <vector>
using namespace std;//写入一个整型数据后接着读出
int main(){ofstream fout("some.bat", ios::out | ios::binary);      //从文件头开始,以二进制的形式写入int x = 120;//从x的内存地址开始传入4字节数据//(const char*)强转是为了让编译器拿到(int*)指针后能将其解释成字符型数据fout.write((const char*) &x, sizeof(int));fout.close();int y;ifstream fin("some.bat", ios::in | ios::binary);//从文件头开始,以二进制的形式写入//从文件开头处取出4字节数据//然后将y地址转成(char*)从而在该地址后面放入4字节数据fin.read((char*) &y, sizeof(int));fin.close();cout << y << endl;return 0;
}

二进制文件读写demo2

  • 先写入三个对象的数据
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cstring>
#include <string.h>
#include <vector>
using namespace std;
struct Student{char name[20];int score;
};//24-Byteint main(){Student s;ofstream OutFile("students.dat", ios::out|ios::binary);while(cin >> s.name >> s.score)OutFile.write((char*) &s, sizeof(s));OutFile.close();return 0;
}
//input:
//Tom 60
//Jack 80
//Jane 40
//^Z Enter
  • 读出并合理地显示内容
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cstring>
#include <string.h>
#include <vector>
using namespace std;
struct Student{char name[20];int score;
};//24-Byteint main(){Student s;ifstream inFile("students.dat", ios::in|ios::binary);if(!inFile){        //空流cerr << "error" << endl;return 0;}while(inFile.read((char*) &s, sizeof(s))){int readBytes = inFile.gcount();	//本次读进来了多少字节数据cout << "readBytes: " << readBytes << endl;cout << s.name << " " << s.score << endl;}inFile.close();return 0;
}
//output:
//readBytes: 24
//Tom 60
//readBytes: 24
//Jack 80
//readBytes: 24
//Jane 40

二进制文件读写demo3

  • 用一个fstream流对象完成读和写的任务
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cstring>
#include <string.h>
#include <vector>
using namespace std;
struct Student{char name[20];int score;
};//24-Byte
//Jane——>Mike
int main(){Student s;fstream iofile("students.dat", ios::in|ios::out|ios::binary);if(!iofile){cerr << "error" << endl;return 0;}iofile.seekp(2 * sizeof(s), ios::beg);      //从文件头开始将写指针移动两个对象大小的跨度——>到第三个对象的首字节//由于Mike和Jane同字符个数,所以写入Mike后'e'的后面已经是'\0'了,其实可以不“+1”让编译器来补终止符。iofile.write("Mike", strlen("Mike") + 1);       iofile.seekg(0, ios::beg);      //防止读指针随机指到其他地方while(iofile.read((char*) &s, sizeof(s))){int readBytes = iofile.gcount();cout << "readByte: " << readBytes << endl;cout << s.name << " " << s.score << endl;}iofile.close();return 0;
}
// output:
// readByte: 24
// Tom 60
// readByte: 24
// Jack 80
// readByte: 24
// Mike 40

总结

  • 文本模式和二进制模式的主要区别在于文本模式会执行一些与文本数据处理相关的特殊转换和处理(比如Windows下所有的'\r\n'会被解释成一个'\n'字符,从而造成数据读取泄漏),而二进制模式不会执行这些操作,二进制模式保留原数据。
  • 这里写入、读出时总利用char*作为参数的其中之一作用:是为了更好地观察、理解数据,否则其他数据类型打开在用户视角是一片乱码(可以用记事本打开dat文件验证)。
http://www.lryc.cn/news/170514.html

相关文章:

  • 详解Linux的grep命令
  • spark6. 如何设置spark 日志
  • glibc: strlcpy
  • 如何在 Buildroot 中配置 Samba
  • SSM02
  • day3_QT
  • js-map方法中调用服务器接口
  • docker 已经配置了国内镜像源,但是拉取镜像速度还是很慢(gcr.io、quay.io、ghcr.io)
  • [linux(静态文件服务)] 部署vue发布后的dist网页到nginx
  • 智华计算机终端保护检查系统使用笔记
  • 前端面试话术集锦第 15 篇:高频考点(React常考进阶知识点)
  • 汽车电子——产品标准规范汇总和梳理(适应可靠性)
  • 计算机是如何工作的(上篇)
  • 数学建模| 优化入门+多目标规划
  • SSM整合Thymeleaf时,抽取公共页面并向其传递参数
  • 接口测试 —— requests 的基本了解
  • 2023年华为杯数学建模研赛D题思路解析+代码+论文
  • AB试验(三)一次试验的规范流程
  • ROI tracking by using OpenCV
  • (leetcode)二叉树最大深度
  • 【golang】调度系列之P
  • Vue3中watch用法
  • 组里来了一个实习生,一行代码引发了一个惨案
  • 随手笔记(四十五)——idea git冲突
  • chacha20 算法流程
  • 准备篇(三)Python 爬虫第三方库
  • 从零开始的PICO开发教程(4)-- VR世界 射线传送、旋转和移动
  • 防止攥改之水印功能组件
  • iOS 17 适配 Xcode 15 问题
  • Element Plus 快速开始