欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C/C++的文件读写

程序员文章站 2024-03-17 11:47:16
...

在没有学习数据库之前,文件读写是学习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<num1;i++)
{
	input >> 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;
}

四、文件读写的功能

  1. 通过文件读写(二进制文件)实现唯一序号的获取功能:https://gitee.com/ZhongShengXueXi/codes/4pifys0qv7b19lxmzd8w330
  2. 待扩展……

 

 

 

相关标签: 文件读写