C/C++的文件读写
时间:2023-02-08 14:00:00
在学习数据库之前,文件读写就是学习C/C 早期遇到的麻烦不仅需要多个标准库函数的配合,还需要考虑存储信息的方式(二进制文件/文本文件)。以下是我最近对文件读写经验的总结。
二进制文件与文本文件的区别在数据存储中,以什么形式存储(示例代码将在下面给出):
如果您直接将数据写入文件,则数据以二进制的形式存储,称为二进制文件;
如果将数据转换为字符串,然后写入文件,则数据以文本的形式存储,称为文本文件。
一、fopen的文件读写
首先,我们必须理解ANSIC标准中C语言标准库中读写文件函数(文本文件):
- 打开文件:FILE *fopen(const char *path, const char *mode);
- 读文件 :int fscanf(FILE *stream, const char *format, ...);
- 写文件 :int fprintf(FILE *stream, const char *format, ...);
- 文件结束:int feof(FILE *stream);
- 关闭文件:int fclose(FILE *fp);
上述文件读写函数的使用规则如下:
- 使用fopen函数,通过文件路径(path)和操作模式(读:"r",写:"w",添加:"a"),获取操作变更文件的文件指针(FILE*);
///通过阅读打开文本文件a.txt FILE* ft_r = fopen("data/a.txt","r"); ///以写作的方式打开文本文件a.txt FILE* ft_w = fopen("data/a.txt","w");
- 使用fscanf函数,通过文件指针(FILE*)、由数据组成的字符串(数据格式化……\n)和数据的变量(数据……),获取文件中的字符串,并对其进行分析,变量。
//从文件a.txt读出一行字符串,分析它 fscanf(ft_r,"%d %s %s\n",&id,name,password);
- 使用fprintf函数,通过文件指针(FILE*)、有数据拼接字符串(数据格式化……\n”)和数据的变量(数据……),将拼接字符串存储在文件中。
//向文件a.txt写入一行数据 fprintf(ft_w,"%d %s %s\n",id,name,password);
- 使用feof函数判断文件是否结束,如果文件结束,则返回非零;如果文件未结束,则返回0。
///阅读文件,直到结束 while(!feof(ft_r)) { //读文件 }
实例:fopen文本文件的一行读写(代码片段)
bool Read_Data_T(tLink TL) { FILE* ft; if((ft=fopen("data/AA_Teacher.txt","r")) == NULL) { ///数据加载失败,程序结束 printf("教师数据为空\n"); exit(0); } //临时参数 tNode* tmp = (tNode*)malloc(sizeof(tNode)); while(!feof(ft)) { fscanf(ft,"%d%s%s%s%hhd\n",&tmp->id,tmp->password,tmp->name,tmp->phone,&tmp->state); Insert_tLink(TL,tmp->id,tmp->password,tmp->name,tmp->phone,tmp->state); } free(tmp); fclose(ft); printf("成功加载教师数据!\n"); return true; }///阅读教师信息 bool Write_Data_T(tLink TL) { FILE* ft; if((ft = fopen("data/AA_Teacher.txt","w")) == NULL) { printf("无法存储教师数据\n"); return false; } tNode* node = TL->head; tNode* tmp = node; while(node != NULL) { fprintf(ft,"%d %s %s %s %hhd\n",node->id,node->password,node->name,node->phone,node->state); tmp = node; node = node->next; free(tmp); } free(TL); fclose(ft); printf("成功存储教师数据!\n"); return true; }///存储教师信息
二、open的文件读写
同样,我们必须首先了解系统函数的文件读写函数(二进制文件/文本文件):
- 打开文件:int open(const char *pathname, int flags, mode_t mode);
- 读文件 :ssize_t read(int fd, void *buf, size_t count);
- 写文件 :ssize_t write(int fd, const void *buf, size_t count);
- 关闭文件:int close(int fd);
上述文件读写函数的使用规则如下:
- 使用open函数,通过文件路径(pathname)和操作模式(读:O_RDONLY,写:O_WRONLY,读写:O_RDWR,创建:O_CREAT,清空:O_TRUNC),需要添加文件权限才能获得文件句柄。
///以读写的方式打开文件a.txt,若不存在,则创建 int fd = open("data/a.txt",O_CREAT|O_RDWR,0644);
- 使用read函数,通过文件句柄(fd)、读取文件数据。
//阅读文件a.txt的数据 char buf[255] = {}; struct stu { int id; char name[20]; char password[20]; }stu; //文本文件 read(fd,buf,sizeof(buf)); //二进制文件 read(fd,&stu,sizeof(stu));
- 使用write函数,通过文件句柄(fd)、将数据写入文件的缓冲区和缓冲区大小。
//将数据写入文件a.txt char buf[255] = 数据字符串!”; struct stu { int id; char name[20]; char password[20]; }stu{110,"keke","mima"}; //文本文件 write(fd,buf,sizeof(buf)); //二进制文件 write(fd,&stu,sizeof(stu));
实例:open读写二进制文件(代码片段)
///发送文件,然后发送文件 while(1) { int ret = read(fd,&tmp,sizeof(Manager)); if(0 == ret) break;//确定文件结束 v_manager.push_back(tmp); } close(fd); //接收一份文件,接收并写入文件 while(1) { if(v_manager.empty()) break;////确定所有数据 tmp = v_manager.back(); v_manager.pop_back(); write(fd,&tmp,sizeof(Manager)); } close(fd);
三、C 的文件读写
我们还需要理解同样的事实C 标准库中的文件读写函数(文本文件):
- 新建阅读数据流对象:ifstream 对象名(文件路径ios::in);
- 新建写数据流对象:ofstream 对象名(“文件路径”,ios::out);
- 文件是否结束:据流对象.eof(),若到文件结尾,返回true;若没到文件结尾,则返回false。
实例:使用C++的文件读写(代码片段):
//创建一个读数据流对象,并进行相关操作
ifstream input(pathname,ios::in);
for(int i=0;i> id >> name >> num2; //读取并解析
if(input.eof()) return; //确定文件读取完全
Employee* em = new Employee(id,name,num2/100,num2%100);
cout << em->getId() << " " << em->getName() << " " << em->getSex() << " " << em->getAge() << endl;
de->getV_employeep().push_back(em);
}
//创建一个写数据流对象,并进行相关操作
ofstream output(pathname,ios::out|ios::trunc);
while(!de->getV_employeep().empty())
{
Employee* em = de->getV_employeep().back();
output << em->getId() << " " << em->getName() << " " << (int)em->getSex()*100+em->getAge() << endl;
de->getV_employeep().pop_back();
delete em;
}
四、文件读写的功能
- 通过文件读写(二进制文件)实现唯一序号的获取功能:https://gitee.com/ZhongShengXueXi/codes/4pifys0qv7b19lxmzd8w330
- 待扩展……