C++文件操作(1)--FILE结构体实现文件读写操作

本篇文章主要讲解C++中的文件操作的相关简介。

一.C++文件简介

c++支持以下两种文件类型:
1.文本文件,又称ASCII字符文件,其每一个字节存放一个ASCII字符。
2.二进制文件,把内存中的数据原样存放到磁盘上。

一个标准的C++文件是一个字节流或者二进制流,将数据当作是一连串的字符。在C++中,对文件的存取是以字符(或字节数)为单位的,这样的文件称为流式文件。

二.文件的打开和关闭

要访问一个文件,我们需要创建一个文件指针。声明方式为:FILE* fp;
指针fp指向FILE结构,用于存放文件信息包括文件名、文件状态和当前位置等。

1.C++中提供fopen函数用于打开一个文件,函数的声明原型如下:
FILE *fopen(const char *filename,const char *mode);

参数简介:
1).filename:指定文件名称
2).mode:指定文件打开方式。方式有以下几种:
“r”":只读方式,为输入打开一个文本文件。
“w”:只写方式,为输出打开一个文本文件。
“a”:追加方式,向文本文件的末尾添加数据。
“rb”:只读方式,为输入打开一个二进制文件。
“wb”:只写方式,为输出打开一个二进制文件。
“ab”:追加方式,向二进制文件的末尾添加数据。
“r+”:读写方式,为读写打开一个文本文件。
“w+”:读写方式,为读写新建一个文本文件。
“a+”:读写方式,为读写打开一个文本文件。
“rb+”:读写方式,为读写打开一个二进制文件。
“wb+”:读写方式,为读写新建一个二进制文件。
“ab+”:读写方式,为读写打开一个二进制文件。

以上的文件打开方式只需要记录,等用的时候再找出需要的方式。

在打开并使用完一个文件后,我们需要关闭它。
C++提供fclose函数用于关闭一个文件,函数的声明如下:
int fclose(FILE *stream);
参数说明:
stream:用于指向文件流对象。

文件访问实例演示:

#include<stdio.h>
#include<iostream>
using namespace std;
int main(){
	FILE* fp;
	fp=fopen("D:\\TestFile\\Readme.txt","r+");
	if(fp!=NULL)
	{
		cout<<"文件存在"<<endl;
	}
	else
	{
		cout<<"文件不存在"<<endl;
	}
	fclose(fp);
	return 0;
}

在这里插入图片描述
先在对应位置创建文件。
运行结果:
在这里插入图片描述
再看下文件打开方式"w+"。删除Readme.txt后,会自动生成Readme.txt。

fp=fopen("D:\\TestFile\\Readme.txt","w+");

在这里插入图片描述
结果:
在这里插入图片描述
其它打开方式,大家可以自行演示。

三.文件的读写

C++提供了文件读写函数,调用fputc函数可以把一个字符写到文件中,调用fgetc函数可以从文件中读取一个字符。
fputc函数和fgetc函数声明如下:
int fputc(int c,FILE* stream);
int fgetc(FILE* stream);

参数说明:
c:指定写入文件的字符。
stream:文件流指针对象。

文件写入字符演示:

#include<stdio.h>
#include<iostream>
using namespace std;
int main(){
	FILE* fp;
	fp=fopen("D:\\TestFile\\Readme.txt","r+");
	if(fp!=NULL)
	{
		cout<<"文件存在"<<endl;
		fputc('a',fp);//写入字符a
		fputc('b',fp);//写入字符b
	}
	else
	{
		cout<<"文件不存在"<<endl;
	}
	fclose(fp);
	fp=fopen("D:\\TestFile\\Readme.txt","r+");
	if(fp!=NULL)
	{
		char ch;
		while(!feof(fp))
		{
			ch=fgetc(fp);
			printf("%c",ch);
		}
	}
	fclose(fp);
	printf("\n\n");
	return 0;
}

结果:
在这里插入图片描述

字符a和b都写进文件中了并且可以读取。

单个单个字符写进文件效率低且代码量很大,如果需要读写文件中的一组字符,可以调用标准函数fread和fwrite。函数声明如下:
size_t fread(void *buffer,size_t size,size_t count,FILE *stream);
size_t fwrite(const void *buffer,size_t size,size_t count,FILE *stream);

参数说明:
1).buffer:指定数据存放缓冲区。
2).size:指定读写的字节数。
3).count:指定读写的数据项,以size参数指定的字节数为单位。
4).stream:文件流指针。

size_t在C语言中就有了。
它是一种“整型”类型,里面保存的是一个整数,就像int、long那样。这种整数用来记录一个大小(size)。size_t的全称应该是size type,就是说“一种用来记录大小的数据类型”。
通常我们用sizeof(XXX)操作,这个操作所得到的结果就是size_t类型。

读写一组字符串字符实例演示:

class Info
{
public:
	char Name[10];
	char Address[10];
	char Post[10];
	Info()
	{
		strcpy(Name,"");
		strcpy(Address,"");
		strcpy(Post,"000000");
	}
	Info(char* name,char* address,char* post)
	{
		strcpy(Name,name);
		strcpy(Address,address);
		strcpy(Post,post);
	}
};

int main(){
	FILE* fp;
	Info info1("张三","北京","100085");
	fp=fopen("Info.txt","wb");
	if(fp!=NULL)
	{
		fwrite(&info1,sizeof(Info),1,fp);
	}
	fclose(fp);

	Info info2;
	fp=fopen("Info.txt","rb");
	if(fp!=NULL)
	{
		fread(&info2,sizeof(Info),1,fp);
	}
	printf("Info2:%s,%s,%s\n",info2.Name,info2.Address,info2.Post);
	fclose(fp);
	printf("\n\n");
	return 0;
}

结果:
在这里插入图片描述
在这里插入图片描述
发现读出文件没问题,但是生成的文件里变成了乱码,这是什么原因呢?
查找资料发现解释如下:
fwrite是二进制写入,而我们使用记事本查看就是乱码。

如何修改呢?
我们可以使用fprintf来替换fwrite。
将fwrite部分修改为:

fprintf(fp,"%s %s %s\n",info1.Name,info1.Address,info1.Post);

运行:
在这里插入图片描述
在这里插入图片描述

四.文件的定位

文件中的位置指针保存了当前读写的位置,每次读写一个字符后,该位置指针自动指向下一个字符位置。
使用rewind函数可以将位置指针定位到文件开头,调用fseek函数可以定位到文件中的任何位置。函数声明如下:
void rewind(FILE *stream);
int fseek(FILE *stream,long offset,int origin);
long ftell(FILE *stream);

参数说明:
stream:指定文件指针。
offset:指定位移量,即移动的字节数。
origin:定位起点:
SEEK_CUR 从文件当前位置开始
SEEK_END 从文件结尾开始
SEEK_SET 从文件开头开始

示例:

int main()
{
	FILE* fp
	Info info1("张三","北京","111111");
	Info info2("李四","上海","222222");
	Info info3;
	Info info4;
	Info info5;
	fp=fopen("Info.txt","wb");
	if(fp!=NULL)
	{
		fwrite(&info1,sizeof(Info),1,fp);
		fwrite(&info2,sizeof(Info),1,fp);
	}
	fclose(fp);
	fp=fopen("Info.txt","rb");
	if(fp!=NULL)
	{
		
		fread(&info3,sizeof(Info),1,fp);
		fread(&info4,sizeof(Info),1,fp);
		
		printf("Info3:%s,%s,%s\n",info3.Name,info3.Address,info3.Post);
		printf("Info4:%s,%s,%s\n",info4.Name,info4.Address,info4.Post);
		
	}
	fclose(fp);
	printf("\n\n");
	fp=fopen("Info.txt","rb");
	if(fp!=NULL)
	{
		fseek(fp,sizeof(Info),SEEK_SET);
		fread(&info5,sizeof(Info),1,fp);
		printf("Info5:%s,%s,%s\n",info5.Name,info5.Address,info5.Post);
	}
	return 0;
}

结果:
在这里插入图片描述
从文件开头开始,定位到第二条记录位置。将SEEK_SET换为SEEK_END.
结果:
在这里插入图片描述
从文件结尾开始定位。

补充:文件的写和读顺序是一一对应的,比如:
fwrite 第一串字符
fwrite 第二串字符
fread 第一串字符
fread 第二串字符

如果交换位置
fwrite 第二串字符
fwrite 第一串字符
fread 第二串字符
fread 第一串字符

C++ FILE结构体实现文件读写就讲解到这,下篇文章将讲解MFC中的文件读写操作类CFile类。

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/baidu_41191295/article/details/111444170