重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
首先是最简单的读写一个字符的函数fputc和fgetc,在这个基础上又出现了putw和getw、fgets和fputs,此外还说过格式化读写函数fprintf和fscanf函数。
创新互联专注于企业成都营销网站建设、网站重做改版、海城网站定制设计、自适应品牌网站建设、H5场景定制、成都商城网站开发、集团公司官网建设、成都外贸网站建设、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为海城等各大城市提供网站开发制作服务。
从原理上来说,只要fputc和fgetc函数基本就可以完成数据的读写操作了,但是在实际的使用中会遇到诸多不便,因此上面那一大堆函数就冒出来了(其实也不多)。上面函数中最方便的就是格式化读写函数fprintf和fscanf了,因为可以一行行的进行读取,但是有个问题就是这两位老人家动作比较慢,fprintf在写文件的时候要把二进制形式表示的数据转换为ASCII码形式,fscanf在读文件的时候又要将ASCII码转换为二进制的形式。
好不容易出来个好用的函数,竟然是个慢性子,聪明的你现在也许就在想了:那能不能不转换,直接读写二进制的数据呢?答案就是fread和fwrite,在需要频繁进行数据读写的时候,使用这两个函数将大大提升效率。
fread和fwrite函数的定义
fread(pBuffer,size,count,pFile);
fwrite(pBuffer,size,count,pFile);
要读写一个数据块的话,无论是读还是写,都需要指定一个起始地址,读的话从这个起始地址读,写的话从这个起始地址写,上面函数定义中的第一个参数pBuffer就是用于指定这个起始地址,size读写的字节数,count则指定读写多少个size大小的数据,pFile是文件结构指针。
fread和fwrite函数使用示例
说到数据块我们自然会想到结构体,如果一个文件中保存的是一个个结构体信息,那每一个结构体信息就可以看做一个数据块了。这里直接用前面文章中我们一直使用的学生成绩信息的结构体:
C语言: 知蚁博客
struct student
{
int nID; //学号
char chName[20]; //姓名
float fScores[3]; //3门课的成绩
};
实例程序有点小复杂的,首先我们自己新建一个txt文件,也就是ASCII文件啦,然后写上一些数据,如下:
1 zhangsan 78.0 79.0 80.0
2 lisi 79.0 77.0 78.0
3 wangwu 90.0 97.0 78.0
4 zhaokai 56.0 57.0 58.0
我们先用ASCII方式打开这个文件,通过fscanf函数读取里面的数据,然后通过fwrite写入到新的二进制格式的文件中,这样我们就得到了一个保存上面信息的二进制格式的文件了,下面就是通过fread函数进行数据的读取了。(记住:fread和fwrite一般用于二进制文件的输入输出,ASCII文件还是不要考虑了)。
C++语言: 知蚁博客
#include "stdio.h"
struct student
{
int nID; //学号
char chName[20]; //姓名
float fScores[3]; //3门课的成绩
};
void main()
{
FILE *pRead,*pWrite;
struct student tStu[4];
struct student *ptStu = NULL;
int nCount = 0;
//ASCII方式打开文件 用于读入
pRead=fopen("stu_scores.txt","r");
if(NULL == pRead)
{
return;
}
//二进制文件打开文件 用于写入
pWrite=fopen("stu_scores_bin.txt","wb");
if(NULL == pWrite)
{
fclose(pRead);
return;
}
//fscanf读取数据,fwrite写入数据
ptStu = tStu;
while(!feof(pRead))
{
fscanf(pRead,"%d %s %f %f %f\n",ptStu-nID,ptStu-chName,ptStu-fScores[0],ptStu-fScores[1],ptStu-fScores[2]);
fwrite(ptStu,sizeof(struct student),1,pWrite);
printf("%d %s %.1f %.1f %.1f\n",ptStu-nID,ptStu-chName,ptStu-fScores[0],ptStu-fScores[1],ptStu-fScores[2]);
ptStu++;
}
fclose(pRead);
fclose(pWrite);
memset(tStu,0×00,sizeof(tStu)); //清空数据
//二进制文件打开文件 用于读取
pRead=fopen("stu_scores_bin.txt","rb");
if(NULL == pRead)
{
printf("open file stu_scores_bin.txt failed");
return;
}
//下面有两种fread的读数据方式,将下面的1换成0,则使用第二种方式
#if 1
//一条条的读取
ptStu = tStu;
nCount = fread(ptStu,sizeof(struct student),1,pRead);
while(nCount0)
{
printf("%d %s %.1f %.1f %.1f\n",ptStu-nID,ptStu-chName,ptStu-fScores[0],ptStu-fScores[1],ptStu-fScores[2]);
ptStu++;
nCount = fread(ptStu,sizeof(struct student),1,pRead);
}
#else
//因为事先知道有4条信息,因此可以直接读取四条信息
fread(tStu,sizeof(struct student),4,pRead);
for(nCount=0; nCount4; nCount++)
{
printf("%d %s %.1f %.1f %.1f\n",tStu[nCount].nID,tStu[nCount].chName,tStu[nCount].fScores[0],tStu[nCount].fScores[1],tStu[nCount].fScores[2]);
}
#endif
fclose(pRead);
}
上面用fread读取的时候,我们既可以一条条的读取,也可以一次读入多条,这就是为什么参数中有size和count的原因
fopen函数完全可以,但为了确保文件是被打开,加了if判断,这是程序设计问题,而且这个函数有返回值
在C语言中,文件操作都是由库函数来完成的。
要读取一个txt文件,首先要使用文件打开函数fopen()。
fopen函数用来打开一个文件,其调用的一般形式为: 文件指针名=fopen(文件名,使用文件方式) 其中,“文件指针名”必须是被说明为FILE 类型的指针变量,“文件名”是被打开文件的文件名。 “使用文件方式”是指文件的类型和操作要求。“文件名”是字符串常量或字符串数组。
其次,使用文件读写函数读取文件。
在C语言中提供了多种文件读写的函数:
·字符读写函数 :fgetc和fputc
·字符串读写函数:fgets和fputs
·数据块读写函数:freed和fwrite
·格式化读写函数:fscanf和fprinf
最后,在文件读取结束要使用文件关闭函数fclose()关闭文件。
下面以格式化读写函数fscanf和fprintf为例,实现对文件A.txt(各项信息以空格分割)的读取,并将它的信息以新的格式(用制表符分割各项信息)写入B.txt,实现对A.txt的处理。
C语言源程序如下所示:
#include stdio.h
#include stdlib.h
#include assert.h
typedef struct student{
char name[32];
int no;
char sex[16];
float score;
} stu;
int main(int argc, char* argv[])
{
//打开文件
FILE * r=fopen("A.txt","r");
assert(r!=NULL);
FILE * w=fopen("B.txt","w");
assert(w!=NULL);
//读写文件
stu a[128];
int i=0;
while(fscanf(r,"%s%d%s%f",a[i].name,a[i].no,a[i].sex,a[i].score)!=EOF)
{
printf("%s\t%d\t%s\t%g\n",a[i].name,a[i].no,a[i].sex,a[i].score);//输出到显示器屏幕
fprintf(w,"%s\t%d\t%s\t%g\n",a[i].name,a[i].no,a[i].sex,a[i].score);//输出到文件B.txt
i++;
}
//关闭文件
fclose(r);
fclose(w);
system("pause");
return 0;
}