第十二章、文件和注册表操作

12.1const char*和char *const

const char*:不能修改其指向的内存中的内容,但可以修改其所指向的内存地址。
char *const:能修改其指向的内存中的内容,但不可以修改其所指向的内存地址。

12.2C语言对文件操作的支持

新建一个单文档类型的MFC程序,取名为File。
然后添加一个子菜单,名称为:文件操作。然后为其添加两个菜单项,并分别添加视类的命令响应函数:
ID:IDM_FILE_WRITE 菜单名称:写入文件 响应函数:OnFileWrite
ID:IDM_FILE_READ 菜单名称:读取文件 响应函数:OnFileRead

12.2.1文件的打开

首先利用fopen函数返回一个指向FILE结构体的指针:
FILE *fopen( const char *filename, const char *mode );
第一个参数表明将要打开的文件;第二个参数是文件打开的模式。

12.2.2文件的写入

向文件中写入可以用fwrite函数:
size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream );
第一个参数指向将要写入的数据;第二个参数以字节为单位的项的大小;第三个参数写入项的最大数目;第四个参数指向FILE类型的指针。

接下来在视类OnFileWrite函数中实现文件的写入操作:

void CFileView::OnFileWrite() 
{
 // TODO: Add your command handler code here
 FILE *pFile=fopen("1.txt","w");
 fwrite("vc++",1,strlen("vc++"),pFile);
}

运行后,单击写入文件菜单项,打开File当前目录,发现新添加了一个该文件。但是打开此文件却发现没有任何内容。关闭运行的程序,再一次打开该文件,就可以看到文件中有内容了,如图。这是因为C语言对文件的操作使用了缓冲文件系统。
在这里插入图片描述

12.2.3文件的关闭

使用fclose函数关闭文件,表示对文件的写入操作已经完成,系统这是会把缓冲区中的内容写入磁盘文件中。

void CFileView::OnFileWrite() 
{
 // TODO: Add your command handler code here
 FILE *pFile=fopen("1.txt","w");
 fwrite("vc++",1,strlen("vc++"),pFile);
 fclose(pFile);
}

运行发现,单击写入文件菜单项后,新增加的文件中就已经出现了内容了。

12.2.4fflush函数

如果希望对每次进行文件操作之后,并不关闭文件,但仍能将缓冲区中的数据立即写入磁盘文件中,这是可以调用fflush函数。

12.2.5文件指针定位

当调用文件写入函数向文件写入数据后,还可以再次写入其他数据。在fwrite(“vc++”,1,strlen(“vc++”),pFile);代码后面添加:
fwrite(“深入详解”,1,strlen(“深入详解”),pFile);
运行后,结果如图。
在这里插入图片描述
文件指针始终指向文件下一个将要写入的位置,所以当第二次调用fwrite函数之后,写入的内容接在第一次写入后面。

如果希望写入数据之后,在文件的开始位置继续写入,那可以利用C语言中fseek函数来实现:
int fseek( FILE *stream, long offset, int origin );
第一个参数指向FILE结构体;第二个参数为设定偏移量;第三个参数指定文件指针起始位置。
第三个参数:SEEK_CUR表示从文件当前位置开始;SEEK_END表示从文件结尾开始;SEEK_SET表示从文件开始处开始。

void CFileView::OnFileWrite() 
{
 // TODO: Add your command handler code here
 FILE *pFile=fopen("1.txt","w");
 fwrite("vc++",1,strlen("vc++"),pFile);
 fseek(pFile,0,SEEK_SET);
 fwrite("深入详解",1,strlen("深入详解"),pFile);
 fclose(pFile);
}

运行结果如图。
在这里插入图片描述

12.2.6文件的读取

对于文件的读取,首先得打开文件,即调用fopen函数得到指向FILE类型的指针,然后如果要读取文件的内容,应该调用fread函数。
size_t fread( void *buffer, size_t size, size_t count, FILE *stream );
该函数与fwrite函数参数含义基本一致,只不过第一个参数是存放数据缓冲区的指针。

void CFileView::OnFileRead() 
{
 // TODO: Add your command handler code here
 FILE *pFile=fopen("1.txt","r");
 char ch[100];
 fread(ch,1,100,pFile);
 fclose(pFile);
 MessageBox(ch);
}

运行结果如图。
在这里插入图片描述
可是发现在深入详解之后出现了一串乱码,原因就是应该在读取到的数据之后添加’\0’字符。
第一种方法就是在写入字符串的后面人为地加上一个’\0’。

void CFileView::OnFileWrite() 
{
 // TODO: Add your command handler code here
 FILE *pFile=fopen("1.txt","w");
 char buf[5]="vc++";
 buf[4]='\0';
 fwrite(buf,1,5,pFile);
 fclose(pFile);
}

读取结果如图。但是这种方式的缺点是多写了一个字节。
在这里插入图片描述
第二种方法就是在定义字符数组之后,利用C语言memset函数将字符数组中所有的数据都设置为0:

void CFileView::OnFileRead() 
{
 // TODO: Add your command handler code here
 FILE *pFile=fopen("1.txt","r");
 char ch[100];
 memset(ch,0,100);
 fread(ch,1,100,pFile);
 fclose(pFile);
 MessageBox(ch);
}

这样当读取完字符串后就碰到’\0’,就会自动停止读取。

第三种方法就是利用ftell和rewind函数:ftell函数将文件的指针移动到文件的结尾处,也就是文件的长度;rewind函数将文件的指针重新放置到文件的开始处。

void CFileView::OnFileRead() 
{
 // TODO: Add your command handler code here
 FILE *pFile=fopen("1.txt","r");
 char *pBuf;
 fseek(pFile,0,SEEK_END);
 int len=ftell(pFile);
 pBuf=new char[len+1];
 rewind(pFile);
 fread(pBuf,1,100,pFile);
 pBuf[len]=0;
 fclose(pFile);
 MessageBox(pBuf);
}

12.2.7二进制文件和文本文件

文件分为二进制文件和文本文件,但实际上都是以二进制方式存储的。对于文本文件来说,他是一种特殊形式的文件,它所存放的每一个字节都可以转换为一个可读的字符,就像打开记事本看到a、b一样。如果以二进制方式保存文件,打开记事本就会看到其他字符。

在写入和读取文件时要保持一致,如果采用文本方式写入,就应该采用文本方式读取;如果采用二进制方式写入,就要采用二进制方式读取。
不管是文本文件还是二进制文件,统一采用二进制方式写入和读取是不会出错的。
不管是文本文件还是二进制文件,都可以采用二进制方式或文本方式打开,然后进行读取和写入。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

身影王座

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值