《(1.5)--第10章 C语言程序设计文件.ppt》由会员分享,可在线阅读,更多相关《(1.5)--第10章 C语言程序设计文件.ppt(41页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第第10章章 文件文件10.1 引例引例10.2 数据文件概述数据文件概述10.3 文件的打开与关闭文件的打开与关闭10.4 文件的操作文件的操作10.5 其他文件操作函数其他文件操作函数 文件是指存储在外存储器上的一组相关数据文件是指存储在外存储器上的一组相关数据的有序集合。的有序集合。文件操作包括文件操作包括:文件的打开、关闭、读出、写文件的打开、关闭、读出、写入和定位等。入和定位等。10.1 引例引例【例例10.1】使用数据文件操作函数,读出使用数据文件操作函数,读出D磁盘根磁盘根目录下的文件目录下的文件file.txt中的数据,将其显示到屏幕上。中的数据,将其显示到屏幕上。#inclu
2、de#includeint main()char str51;FILE*fp;if(fp=fopen(D:file.txt,r)=NULL)printf(File open error!n);exit(1);fgets(str,51,fp);printf(%s(from file file.txt),str);if(fclose(fp)printf(Can not close the file!n);exit(1);return 0;运行结果:运行结果:12345(from file file.txt)10.2 数据文件概述数据文件概述 按照数据存储的编码方式,可以将文件分为按照数据存储的编码
3、方式,可以将文件分为ASCII文件文件和二进制文件两种。假设文件中的内容为和二进制文件两种。假设文件中的内容为“12345”,则:,则:10.2.1 ASCII文件与二进制文件文件与二进制文件ASCII文件(文本文件)文件(文本文件)文件中:文件中:00110001 00110010 00110011 00110100 00110101 信息内容:信息内容:1 2 3 4 5 二进制文件二进制文件文件中:文件中:00110000 00111001 信息内容:信息内容:12345流文件流文件 在在C语言中,无论是语言中,无论是ASCII文件还是二进制文件,文件还是二进制文件,都是按顺序构成的比特
4、序列,将比特序列以字节为都是按顺序构成的比特序列,将比特序列以字节为单位划分为字符流(单位划分为字符流(ASCII文件)或字节流(二进文件)或字节流(二进制文件),这样的文件又被称为制文件),这样的文件又被称为流式文件或流文件。流式文件或流文件。从本质上说,从本质上说,ASCII文件和二进制文件之间没有文件和二进制文件之间没有区别,所有文件在外存储器上都只有一种存储方式区别,所有文件在外存储器上都只有一种存储方式(比特)。(比特)。ASCII文件只是二进制文件的一个特例。文件只是二进制文件的一个特例。尽管文件被区分为尽管文件被区分为ASCII文件和二进制文件,但文件和二进制文件,但在实际打开文
5、件时并不会对文件格式做检查,因而在实际打开文件时并不会对文件格式做检查,因而可以将可以将ASCII文件以二进制方式打开或将二进制文件文件以二进制方式打开或将二进制文件以以ASCII文件方式打开。文件方式打开。10.2.2 缓冲文件系统缓冲文件系统 对于每个正在使用的文件,操作系统为其在内存中开辟一段对于每个正在使用的文件,操作系统为其在内存中开辟一段存储区,用于存储从文件输入的内容或者需要输出到文件的内容,存储区,用于存储从文件输入的内容或者需要输出到文件的内容,这段存储区被称为缓冲区。通过缓冲区处理文件的系统称为缓冲这段存储区被称为缓冲区。通过缓冲区处理文件的系统称为缓冲文件系统。文件系统。
6、缓冲区有两种类型,输入缓冲区和输出缓冲区,缓冲区有两种类型,输入缓冲区和输出缓冲区,系统每次读文件时,会将文件中的一批数据都读入输入缓系统每次读文件时,会将文件中的一批数据都读入输入缓冲区,当所需读取的数据不在缓冲区时,系统将再次从文件中冲区,当所需读取的数据不在缓冲区时,系统将再次从文件中读入一批数据;写文件时,则在输出缓冲区满时才会有实际的读入一批数据;写文件时,则在输出缓冲区满时才会有实际的写文件操作,输出缓冲区未满或关闭之前,实际的输出操作并写文件操作,输出缓冲区未满或关闭之前,实际的输出操作并不会被执行。不会被执行。10.2.3 文件结构与文件类型指针文件结构与文件类型指针 为了有效
7、地使用文件缓冲区,系统将缓冲区的细节封装到了为了有效地使用文件缓冲区,系统将缓冲区的细节封装到了一个结构体中,称为文件结构。该结构定义包含在一个结构体中,称为文件结构。该结构定义包含在stdio.h头文头文件中。定义如下:件中。定义如下:typedef structshort level;/*缓冲区的程度缓冲区的程度*/unsigned flags;/*文件状态标识文件状态标识*/char fd;/*文件描述符文件描述符*/unsigned char hold;short bsize;/*缓冲区的大小缓冲区的大小*/unsigned char *buffer;/*缓冲区缓冲区*/unsigne
8、d char *curp;/*读写指针读写指针*/unsigned istemp;short token;FILE;FILE类型的指针被称为文件指针。例如类型的指针被称为文件指针。例如:FILE*fp 在操作系统中,把外部设备也当作一个文在操作系统中,把外部设备也当作一个文件进行管理的。例如,键盘通常作为标准输入件进行管理的。例如,键盘通常作为标准输入设备,显示器及打印机称为标准输出设备。设备,显示器及打印机称为标准输出设备。n标准的输入文件标准的输入文件键盘,文件指针是键盘,文件指针是stdinn标准的输出文件标准的输出文件显示器,文件指针是显示器,文件指针是stdout 文件指针文件指针s
9、tdin和和stdout不需要用户定义,它不需要用户定义,它们已被包含在们已被包含在stdio.h头文件中,由编译系统自头文件中,由编译系统自动处理。动处理。10.2.4 标准输入标准输入/输出设备文件输出设备文件10.3 文件的打开与关闭文件的打开与关闭 C语言中,打开文件使用语言中,打开文件使用fopen()函数函数 fopen(文件路径文件路径,文件打开方式文件打开方式)路径中的路径中的“”都使用都使用“”表表示示例如例如:fopen(D:file.txt,r);表示以只读方式打开表示以只读方式打开D磁盘的磁盘的file.txt文件文件 文件打开方式文件打开方式含义含义说明说明r(只读)
10、(只读)以以输输入入方方式式打打开开一一个个文文本文件,文件只能读。本文件,文件只能读。文文件件必必须须存存在在,否否 则则 fopen()函函数数将将返返回回NULL。r+(读写)(读写)为为输输入入/输输出出打打开开一一个个文文本文件。本文件。rb(只读)(只读)以以输输入入方方式式打打开开一一个个二二进制文件,文件只能读。进制文件,文件只能读。rb+(读写)(读写)为为输输入入/输输出出打打开开一一个个二二进制文件。进制文件。w(只写只写)以以输输出出方方式式建建立立一一个个文文本文件,文件只能写。本文件,文件只能写。不不要要求求文文件件一一定定存存在在,若若文文件件不不存存在在则则创创
11、建建该该文文件件,如如果果文文件件已已经经存存在在,则则清清空空文文件件中中原原有有内内容容。如如果果打打开开操操作作失失败败则则fopen()函函数数返回返回NULL。w+(读写读写)为为输输入入/输输出出建建立立一一个个文本文件。文本文件。wb(只写只写)以以输输出出方方式式建建立立一一个个二二进制文件,文件只能写。进制文件,文件只能写。wb+(读写读写)为为输输入入/输输出出建建立立一一个个二进制文件。二进制文件。a(追加追加)向向文文本本文文件件尾尾添添加加数数据,文件只能写。据,文件只能写。不不要要求求文文件件一一定定存存在在,若若不不存存在在则则创创建建该该文文件件,若若文文件件已
12、已经经存存在在,则则只只能能在在原原有有数数据据之之后后添添加加内内容容。如如果果打打开开操操作作失失败败则则fopen()函数返回函数返回NULL。a+(读写读写)为为输输入入/输输出出打打开开一一个文本文件。个文本文件。ab(追加追加)向向二二进进制制文文件件尾尾添添加加数据,文件只能写。数据,文件只能写。ab+(读写读写)为为输输入入/输输出出打打开开一一个二进制文件。个二进制文件。【例例10.2】已知已知E盘根目录下的一个盘根目录下的一个ASCII文件文件data.txt中存储了中存储了50个字符,若需要修改该文件中个字符,若需要修改该文件中已经存在的若干个字符,只能调用一次已经存在的
13、若干个字符,只能调用一次fopen函数,函数,已有声明语句已有声明语句“FILE*fp;”,则,则fopen()函数的正确函数的正确调用形式是调用形式是 。Afp=fopen(e:data.dat,r+);Bfp=fopen(e:data.dat,w+);Cfp=fopen(e:data.dat,a+);Dfp=fopen(e:data.dat,w);文件打开方式文件打开方式nfopen()函数的返回值是一个函数的返回值是一个FILE类型的指针,类型的指针,打开成功,返回文件指针。否则,返回一个打开成功,返回文件指针。否则,返回一个NULL(空值)(空值)使用使用fopen()函数时需要注意的
14、五个方面函数时需要注意的五个方面n使用使用fopen()返回值前,需要判断文件是否打返回值前,需要判断文件是否打开成功,例如:开成功,例如:if(fp=fopen(D:file.txt,r)=NULL)printf(File open error!n);exit(1);/*终止程序的执行终止程序的执行*/n文件打开后,文件的打开方式将被固定下来,文件打开后,文件的打开方式将被固定下来,直至文件被关闭都不能改变。直至文件被关闭都不能改变。n允许同时打开多个文件,每打开一个文件就需允许同时打开多个文件,每打开一个文件就需要一个要一个FILE指针,若需要同时打开多个文件,需指针,若需要同时打开多个文
15、件,需要定义多个要定义多个FILE指针。不允许同一个文件在关闭指针。不允许同一个文件在关闭前被再次打开。前被再次打开。nC语言中,语言中,ASCII文件与二进制文件的打开方式文件与二进制文件的打开方式可以通用。例可以通用。例13.1中,可以将打开文件的语句替中,可以将打开文件的语句替换为换为fp=fopen(D:file.txt,rb+);格式为:格式为:fclose(文件指针文件指针)fclose()执行成功,则返回执行成功,则返回0,否则返回,否则返回EOF(EOF是头文件是头文件stdio.h中定义的宏常量,值为中定义的宏常量,值为-1)。)。关闭文件操作的含义是:将文件缓冲区中还未写入
16、文关闭文件操作的含义是:将文件缓冲区中还未写入文件的数据写入文件,同时释放文件占用的缓冲区单元。件的数据写入文件,同时释放文件占用的缓冲区单元。10.3.2 文件的关闭文件的关闭文件操作完成后,必须关闭文件。文件操作完成后,必须关闭文件。关闭文件常常使用条件判断,例如:关闭文件常常使用条件判断,例如:if(fclose(fp)/*关闭文件关闭文件*/printf(Can not close the file!n);exit(1);10.4 文件的操作文件的操作10.4.1 字符方式文件读写函数字符方式文件读写函数fgetc()和和fputc()调用形式为:调用形式为:fputc(ch,fp);
17、ch=fgetc(fp);其中其中ch为待写入文件或由文件读出的字符,为待写入文件或由文件读出的字符,fp是指向文件的文件指针。是指向文件的文件指针。#includeint main()char ch;FILE*fp;fp=fopen(d:asc.txt,w);if(fp=NULL)printf(nfile open error!),exit(1);printf(Please input characters:n);ch=getchar();运行结果:运行结果:Please input characters:Hello!Good-bye!#【例例10.3】从键盘输入若干个字符,写到文件从键盘输
18、入若干个字符,写到文件“d:asc.txt”中。中。while(ch!=#)fputc(ch,fp);ch=getchar();if(fclose(fp)printf(Can not close the file!n);exit(1);return 0;#includeint main()char ch;FILE*fp;fp=fopen(d:asc.txt,r);if(fp=NULL)printf(nfile open error!),exit(1);ch=fgetc(fp);运行结果:运行结果:Hello!Good-bye!对于对于ASCII文件,文件,fgetc()函数返回函数返回EOF,
19、表示已经,表示已经读到文件末尾了;但对于读到文件末尾了;但对于二进制文件,只能用二进制文件,只能用feof()函数判断是否已经到文函数判断是否已经到文件末尾。件末尾。while(ch!=EOF)putchar(ch);ch=fgetc(fp);fclose(fp);return 0;【例例10.4】将例将例13.3建立的文件建立的文件“d:asc.txt”中的内容输中的内容输出到显示器。出到显示器。10.4.2 字符串文件读写函数字符串文件读写函数fgets()和和fputs()字符串通常使用字符串通常使用fputs()或或fgets()函数:函数:fputs(str,fp);fgets(st
20、r,n,fp);其中,其中,str表示要写入的字符串,可以为字表示要写入的字符串,可以为字符数组名、字符型指针变量或字符串常量,符数组名、字符型指针变量或字符串常量,fp是文件指针。是文件指针。#include int main()char str80=0;FILE*fp;if(fp=fopen(d:string.txt,w)=NULL)printf(cannot open the file.n);exit(1);printf(Please input strings:n);gets(str);运行结果:运行结果:Please input strings:Hello!Good-bye!Z 写入
21、多个字符串,写入多个字符串,ctrl+z结结束束,ctrl+z表示表示stdin输入输入流结束,是从键盘输入的流结束,是从键盘输入的EOF。while(!feof(stdin)fputs(str,fp);fputs(n,fp);gets(str);fclose(fp);return 0;【例例10.5】向文件向文件“d:string.txt”写入多行字符写入多行字符串。串。#include int main()char str50;FILE*fp;if(fp=fopen(d:string.txt,r)=NULL)printf(cannot open the file.n);exit(1);fg
22、ets(str,50,fp);while(!feof(fp)printf(%s,str);fgets(str,50,fp);fclose(fp);return 0;运行结果:运行结果:Hello!Good-bye!【例例10.6】读文件读文件“d:string.txt”中的内容输出到显示器中的内容输出到显示器上。上。10.4.3 格式化文件读写函数格式化文件读写函数fscanf()和和fprintf()格式化输入格式化输入/输出函数的一般调用形式为:输出函数的一般调用形式为:fprintf(fp,格式控制字符串格式控制字符串,输出项列表输出项列表);fscanf(fp,格式控制字符串格式控制字
23、符串,输入项列表输入项列表);其中,其中,fp为指向待写文件的文件指针,格式控制字符为指向待写文件的文件指针,格式控制字符串,输出项列表与串,输出项列表与printf()或或scanf()函数中的相同。函数中的相同。#includeint main()int i,n6=1,2,3,4,5,6;char c6=a,b,c,d,e,f;FILE*fp;if(fp=fopen(d:format.txt,w)=NULL)printf(cannot open the file.n);exit(1);for(i=0;i6;i+)fprintf(fp,%c:%d,ci,ni);fclose(fp);retu
24、rn 0;【例例10.7】将数组将数组n6=1,2,3,4,5,6和和c6=a,b,c,d,e,f的内容成对写入文件的内容成对写入文件d:format.txt。写入后,文件中的内容为。写入后,文件中的内容为a:1b:2c:3d:4e:5f:6。#includeint main()int i,n;char c;FILE*fp;if(fp=fopen(d:format.txt,r)=NULL)printf(cannot open the file.n);exit(1);for(i=0;i6;i+)fscanf(fp,%c:%d,&c,&n);printf(%c:%d,c,n);fclose(fp)
25、;return 0;运行结果:运行结果:a:1b:2c:3d:4e:5f:6【例例10.8】读读d:format.txt文件内容,将结果显示在显示器上。文件内容,将结果显示在显示器上。10.4.4 数据块读写函数数据块读写函数fread()和和fwrite()fread()和和fwrite()函数用于读写一组数据,函数用于读写一组数据,多用于二进制文件。多用于二进制文件。调用形式为:调用形式为:fwrite(buffer,size,count,fp)fread(buffer,size,count,fp)lbuffer是指向待写入或读出数据的指针是指向待写入或读出数据的指针lsize是要写或读数
26、据块的字节数是要写或读数据块的字节数lcount是要写或读的数据块的个数是要写或读的数据块的个数lfp为文件指针。为文件指针。fp必须指向一个以写或读方必须指向一个以写或读方式打开的文件。式打开的文件。#include struct man char name10;int age;man2=zhangsan,19,lisi,20;int main()FILE*fp;if(fp=fopen(d:man.dat,wb)=NULL)printf(Cannot open file!);exit(0);fwrite(man,sizeof(struct man),2,fp);fclose(fp);retu
27、rn 0;【例例10.9】将将man数组的内容写入文件数组的内容写入文件d:man.dat。运行结果:运行结果:zhangsan:19lisi:20#include struct manchar name10;int age;man2;int main()FILE*fp;if(fp=fopen(d:man.dat,rb)=NULL)printf(Cannot open file!);exit(1);fread(man,sizeof(struct man),2,fp);printf(n%s:%d,man0.name,man0.age);printf(n%s:%d,man1.name,man1.a
28、ge);fclose(fp);return 0;【例例10.10】将文件将文件d:man.dat的内容读出并输的内容读出并输出到屏幕上出到屏幕上。10.5 其他文件操作函数其他文件操作函数feof()函数的作用是检测文件是否结束,函数函数的作用是检测文件是否结束,函数格式如下:格式如下:feof(fp)其中,其中,fp为文件指针。函数的功能是检测为文件指针。函数的功能是检测fp所所指文件的读写指针是否已经到达文件尾部,若指文件的读写指针是否已经到达文件尾部,若是则返回非零值,否则返回是则返回非零值,否则返回0。1.feof()函数函数#includeint main()FILE*fp1,*fp
29、2;if(fp1=fopen(d:man.dat,r)=NULL)printf(nfile open error!),exit(1);if(fp2=fopen(d:man1.dat,w)=NULL)printf(nfile open error!),exit(1);while(!feof(fp1)fputc(fgetc(fp1),fp2);fclose(fp1);fclose(fp2);return 0;【例例10.11】将例将例13.9生成的生成的man.dat数据文数据文件,复制一份保存为件,复制一份保存为man1.dat。函数的作用是使文件指针指向文件的头部。函数的作用是使文件指针指向文
30、件的头部。函数调用形式为:函数调用形式为:rewind(fp);fp是文件指针,指向所打开的文件。调用是文件指针,指向所打开的文件。调用rewind()函数后,读写指针被置于文件开始位置,下函数后,读写指针被置于文件开始位置,下一次的读写操作将在文件第一个字节进行。一次的读写操作将在文件第一个字节进行。2.rewind()函数函数#includeint main()char ch;FILE*fp;fp=fopen(D:asc.txt,r);if(fp=NULL)printf(nfile open error!),exit(1);ch=fgetc(fp);putchar(ch);rewind(f
31、p);ch=fgetc(fp);putchar(ch);fclose(fp);return 0;【例例10.12】使用使用rewind()函数重新读文件函数重新读文件asc.txt开始的内容。开始的内容。运行结果:运行结果:hhC语言中,文件也可以随机读写,称为随机语言中,文件也可以随机读写,称为随机文件。随机文件的读写定位可以通过文件。随机文件的读写定位可以通过fseek()函数完成。函数格式如下:函数完成。函数格式如下:fseek(fp,offset,fromwhere);函数的功能是将函数的功能是将fp所指文件的读写指针移动所指文件的读写指针移动到从到从fromwhere偏移偏移offs
32、et的地方,设置成的地方,设置成功,返回功,返回0,失败返回,失败返回-1。随机文件读写定位随机文件读写定位 fp是文件指针,是文件指针,offset表示移动偏移量,它应是表示移动偏移量,它应是long型数据,型数据,使用常量时,要加上后缀使用常量时,要加上后缀“L”;为正时表示从当前位置向后计;为正时表示从当前位置向后计算,算,offset为负时,表示按相反方向计算偏移量。为负时,表示按相反方向计算偏移量。fromwhere可可用标识符或数字表示,有三种情况,见表用标识符或数字表示,有三种情况,见表10.2。fseek()函数对随机文件操作时,控制文件函数对随机文件操作时,控制文件指针的方式
33、如图所示。指针的方式如图所示。fseek(fp,50L,0);以文件开始位置为基准,文件指针移到以文件开始位置为基准,文件指针移到50字节处字节处fseek(fp,50L,1);以文件指针当前位置为基准,文件指针向文件尾移动以文件指针当前位置为基准,文件指针向文件尾移动50字节字节fseek(fp,-50L,1);以文件指针当前位置为基准,文件指针向文件头移动以文件指针当前位置为基准,文件指针向文件头移动50字节字节fseek(fp,-50L,2);以文件末尾位置为基准,文件指针向文件头移动以文件末尾位置为基准,文件指针向文件头移动50字节字节例如:例如:3.fseek()函数函数#inclu
34、de#define N 3struct student char no10;char name15;int score3;main()int i,j,n;FILE*fp;struct student s,studN=150624301,zhangsan,75,87,0,150624302,lisi,82,88,0,150624303,wangwu,79,93,0;for(i=0;iN;i+)for(j=0;j2;j+)studi.score2+=studi.scorej;printf(student information:n);【例例10.13】二进制随机文件操作示例。二进制随机文件操作示例
35、。接下页接下页for(i=0;iN;i+)printf(%11s%s%d%d%d,studi.no,studi.name,studi.score0,studi.score1,studi.score2);printf(n);fp=fopen(D:score.dat,w);for(i=0;iN;i+)fwrite(&studi,sizeof(struct student),1,fp);fclose(fp);fp=fopen(D:score.dat,rb);printf(Please input number:);scanf(%d,&n);printf(output student informat
36、ion:n);fseek(fp,(n-1)*sizeof(s),0);fread(&s,sizeof(s),1,fp);printf(%11s%s%d%d%d,s.no,s.name,s.score0,s.score1,s.score2);运行结果:运行结果:student information:150624301 zhangsan 75 87 162 150624302 lisi 82 88 170 150624303 wangwu 79 93 172Please input number:3 output student information:150624303 wangwu 79 9
37、3 172ftell()函数的作用是获取文件指针读写的位置,格式函数的作用是获取文件指针读写的位置,格式如下:如下:ftell(fp);其中,其中,fp为文件指针。函数的功能是返回为文件指针。函数的功能是返回fp所指文件所指文件的读写指针相对于文件头的位置,成功则返回一个大于的读写指针相对于文件头的位置,成功则返回一个大于0L的值,否则返回的值,否则返回-1L。例如,下面代码的执行结果为。例如,下面代码的执行结果为14。fseek(fp,sizeof(struct man),SEEK_SET);/*跳过第一个数据项跳过第一个数据项*/printf(n%ld,ftell(fp);4.ftell(
38、)函数函数10.6 文件程序设计示例文件程序设计示例【例例10.14】编写程序,接受从键盘输入的编写程序,接受从键盘输入的n值,找出小于值,找出小于n的所有素数及它们的反序数,将找到的素数和它们的反的所有素数及它们的反序数,将找到的素数和它们的反序数输出并写到结果文件序数输出并写到结果文件myf1.out中。中。#include#includeint prime(int m,int x,int y)int i,k=0,s,n;while(-m)for(i=2;i=sqrt(m);+i)if(m%i=0)break;if(i=sqrt(m)continue;xk=m;s=0;n=m;接下页接下页
39、while(n)s=s*10+n%10;n/=10;yk+=s;return k-1;int main()int n,i,a100,b100,m;FILE*fp;if(fp=fopen(d:myf1.out,w)=NULL)printf(不能打开文件不能打开文件!n);exit(1);printf(请输入一个数:请输入一个数:);scanf(%d,&n);m=prime(n,a,b);接下页接下页for(i=0;im;i+)printf(%5d,ai);fprintf(fp,%5d,ai);printf(n);fprintf(fp,n);for(i=0;im;i+)printf(%5d,bi);fprintf(fp,%5d,bi);if(fclose(fp)printf(不能关闭文件不能关闭文件!n);exit(1);return 0;运行结果:运行结果:请输入一个数:请输入一个数:30 29 23 19 17 11 7 5 3 2 92 32 91 71 11 7 5 3 2