1、教学内容教学内容:9.1 文件概述文件概述9.2*文件的打开与关闭文件的打开与关闭9.3*文件的读写操作文件的读写操作9.4*位置指针与文件定位位置指针与文件定位9.5 出错检测出错检测本章要点本章要点本章作业与上机实践本章作业与上机实践9.1 9.1 文件概述文件概述1文件与文件名文件与文件名文件文件是指存放在外部存储介质存储介质上的数据集合数据集合。为标识一个文件,每个文件都必须有一个文件名文件名,其一般结构为:主文件名主文件名.扩展名扩展名 文件命名规则,遵循操作系统操作系统的约定。文件的内容文件的类别2文件分类文件分类(1)根据文件的内容内容:程序程序文件+数据数据文件。(2)根据文件
2、的组织形式组织形式:顺序顺序存取文件+随机随机存取文件。源源文件、目标目标文件+可执行可执行文件(3)在C语言中,根据存储形式分为:ASCIIASCII码码文件:逐个字符字符存储其ASCIIASCII码码。1个字节存储1个字符,因而便于对字符进行逐个处理,所以适合存储文本内容。如果用于存储数值,则一般占用存储空间较多,而且要花费转换时间(ASCII码与二进制之间的转换)。二进制二进制文件:内存内存中的数据,原样输出。用二进制形式存储数值,可以节省存储空间和转换时间;但1个字节并不对应1个字符,不能直接输出字符形式。0110010000000000内存中的存储形式0011000000110000
3、00110001 ASCII码存储形式 (1)(0)(0)01100100二进制存储形式 例如,整数100:ASCII码形式:每位数字占用1B,共3B。二进制形式:1个字节就够用,如下图所示:3读文件与写文件读文件与写文件(1)所谓读读文件是指,将磁盘文件中的数据传送到计算机内存的操作:文件文件(磁盘)内存内存(2)所谓写写文件是指,从计算机内存向磁盘文件中传送数据的操作:内存内存 文件文件(磁盘)4构成文件的基本单元与流式文件构成文件的基本单元与流式文件语言将文件看作是,一个字符字符(ASCII码文件)或字节字节(二进制文件)流,如下图所示:字符n-1字符i字符1字符0读写指针这种文件称为流
4、流式文件。5文件类型文件类型FILE系统给每个打开的文件文件都在内存中开辟一个区域,用于存放文件的有关信息信息(如文件名、文件位置等)。这些信息保存在一个FILE结构类型的变量(由系统定义)中。返回返回必须大写9.29.2*文件的打开与关闭文件的打开与关闭对文件进行操作之前,必须先打开该文件;使用结束后,应立即关闭,以免数据丢失。9.2.1*文件的打开文件的打开fopen()函数函数1用法:FILE *fopen(文件名文件名,操作方式操作方式);2功能:返回一个指向文件的指针。3函数原型:stdio.h。对文件操作的库函数,函数原型均在该头文件中。(1)“文件名”是指要打开(或创建)的文件名
5、。如果使用字符数组数组(或指针或指针),则无需双引号。如果文件不在搜索路径搜索路径下,则必须使用全称全称。(2)“操作方式”如下表所示:带绝对路径打开目的ASCII码文件二进制二进制文件备 注只读(输入)rrb文件已经存在只写(输出)wwb有则删无则建向文件尾追加数据aab文件已经存在读/写文件r+a+rb+ab+文件已经存在创建新文件w+wb+有则删无则建(3)如果打开操作失败失败,则fopen()函数返回一个空空指针指针NULL(其值在头文件stdio.h中被定义为)。为增强程序可靠性,常用如下方法打开一个文件:if(fp=fopen(文件名文件名,操作方式操作方式)=NULL)print
6、f(can not open this filen);exit(0);关闭所有打开的文件,结束程序运行。9.2.2 文件的关闭文件的关闭fcolse()函数函数1用法:int fclose(FILE *文件指针文件指针);2功能:关闭“文件指针”所指向的文件。3函数返回值:正常关闭,返回值为;否则,返回值为非。例如,fclose(fp);/*关闭fp所指向的文件*/返回返回9.39.3*文件的读文件的读/写操作写操作文件打开之后,就可以对它进行读/写操作了。9.3.1 读写一个字符读写一个字符9.3.2 读写一个字符串读写一个字符串9.3.3 读写一个数据块读写一个数据块9.3.4 格式化读写
7、格式化读写9.3.5 读写函数的选用原则读写函数的选用原则返回返回9.3.1 9.3.1 读写一个字符读写一个字符1写写1个字符到文件中个字符到文件中fputc()函数函数例例9.19.1 从键盘上输入一个字符串(以“”作为结束字符),以ASCII码形式存储到一个磁盘文件diskfile.txt中。#include stdio.h#include conio.hvoid main()FILE*fp;char ch;if(fp=fopen(diskfile.txt,w)=NULL)printf(can not open this file,press any key to exit.);getc
8、h();exit(0);/*输入字符,并存储到指定文件中*/for(;(ch=getchar()!=;)fputc(ch,fp);fclose(fp);Next必须大写 库函数库函数fputc()(1)用法:int fputcfputc(字符数据字符数据,文件指针文件指针);(2)功能:将字符数据写到指定文件中,并将读读/写位置指针写位置指针向前移动1个字节(即指向下一个写入位置)。(3)返回值:输出成功,返回输出的字符数据;输出失败,返回一个符号常量EOF(其值在头文件stdio.h中,被定义为-1)。返回程序常量常量/变量变量注:所有读写函数均自动自动调整该 指针,到下一个读写位置。2从文
9、件中读从文件中读1个字符个字符fgetc()和和feof()函数函数例例9.2 顺序显示例例9.1创建的磁盘文件diskfile.txt。#include stdio.h#include conio.hvoid main()FILE*fp;char ch;if(fp=fopen(diskfile.txt,r)=NULL)printf(can not open source file,press any key to exit.);getch();exit(0);for(;(ch=fgetc(fp)!=EOF;)putchar(ch);fclose(fp);getch();Next 库函数库函数
10、fgetc()(1)用法:int fgetcfgetc(文件指针文件指针 );(2)功能:从指定文件中读1个字符,并将读写位置指针向前移动1个字节。该函数无出错返回值。例如:ch=fgetc(fp);返回程序 符号常量符号常量EOF 在对ASCIIASCII码文件码文件执行读读入操作时,如果遇到文文件尾件尾,则返回一个文件结束标志EOFEOF(其值在头文件stdio.h中被定义为-1)。End Of File,只适用于ASCII码文件 库函数库函数feof()(1)用法:int feoffeof(文件指针文件指针 );(2)功能:在执行读读文件操作时,如果遇到文件文件尾尾,则函数返回逻辑真真(
11、1);否则,则返回逻辑假假(0)。feof()函数同时适用于ASCII码文件和二进制文件二进制文件(只能使用该函数,不能使用EOFEOF)。返回程序 例例9.3 设计一个程序:实现制作任意1个ASCII码文件的副本(文件名由用户任意指定)。算法设计要点:(1)制作副本可以有两种方法:一种是使用带参主函数;另一种是在程序运行时,提示用户输入文件名。本例采用第一种方法。(2)首先校验参数个数,然后依次打开、并校验源文件和目标文件,如果校验均通过,则进行复制操作。/*使用格式:可执行文件名可执行文件名 源文件名源文件名 目标文件名目标文件名*/#include stdio.h#include con
12、io.hvoid main(int argc,char*argv)FILE*input,*output;char ch;if(argc!=3)printf(参数个数不对n);printf(n Usage:可执行文件名 source-file dest-file);exit(0);源文件指针目标文件指针 if(input=fopen(argv1,r)=NULL)/*打开源文件失败*/printf(can not open source filen);exit(0);if(output=fopen(argv2,w)=NULL)/*创建目标文件失败*/printf(can not create de
13、stination filen);exit(0);/*复制源文件到目标文件中*/for(;(!feof(input);)fputc(fgetc(input),output);fclose(input);fclose(output);/*关闭文件*/返回返回9.3.2 9.3.2 读写一个字符串读写一个字符串fgets()fgets()和和fputs()fputs()例例9.4 密码管理程序。要求:(1)密码设置(密码长度69个字符);(2)加密存储到1个ASCII码文件中;(3)登录密码校验。算法设计要点:算法设计要点:(1)密码设置(密码长度69个字符):请参阅例6.6。(2)加密存储到1个
14、ASCII码文件:字符串加密,请参阅例6.4。本例直接利用fputs()函数,将加密后的密文写入密码文件password.txt。(3)登录密码校验:首先提示用户输入输入密码,然后使用同一加密算法对用户输入的密码字符串进行加密加密,再与密码文件中存储的密文密文比较。为突出本例重点对文件的读写操作,密码设置和密码串加密,留给读者自己设计和实现,本例对密码字符串进行不加密存储和校验。#include stdio.h#include conio.hvoid main()FILE*fp;char password13,password213;if(fp=fopen(password.txt,w)=NU
15、LL)printf(n can not open this file,press any key to exit.);getch();exit(0);/*设置、并存储密码*/printf(n Setup a password(6-9 characters):);gets(password);fputs(password,fp);fclose(fp);/*重新打开密码文件,读出密码字符串用于登录校验*/if(fp=fopen(password.txt,r)=NULL)printf(n can not open this file,press any key to exit.);getch();e
16、xit(0);fgets(password,13,fp);fclose(fp);printf(n Input the password(6-9 characters):);gets(password2);if(strcmp(password2,password)=0)/*密码正确*/printf(n The password is correct,press any key to continue.);else printf(n The password is incorrect,press any key to exit.);getch();返回返回 库函数库函数fputs()向指定文件输出
17、一个字符串向指定文件输出一个字符串用法:int fputs(fputs(字符串,文件指针字符串,文件指针);功能:向指定文件输出一个字符串,并将读写位置指针向前移动length(串长)个字节。如果输出成功,则函数返回值为0;否则,为非0值。返回程序返回程序 库函数库函数fgets()从文件中读一个字符串从文件中读一个字符串 用法:char *fgetsfgets(指针,串长指针,串长+1+1,文件指针,文件指针 );功能:从指定文件中读入一个字符串,存入“字符数组/指针”中,并在尾端自动加一个结束标志0;同时,将读写位置指针向前移动length(串长)个字节。注注:如果在读入规定长度之前,遇到
18、文件尾EOF或换行符,读入即结束。返回程序返回程序为结束标志预留9.3.3 9.3.3 读读/写一个数据块写一个数据块fread()fread()和和fwrite()fwrite()实际应用中,常常要求1次读写1个数据块。1读1个数据块fread()int fread(void*buffer,int size,int count,FILE*fp);从fp所指向文件的当前位置开始,一次读入size个字节,重复count次,并将读入的数据存放到从buffer(起始地址)开始的内存中;同时,将读写位置指针向前移动size*count个字节。2 写1个数据块fwrite()int fwrite(voi
19、d*buffer,int size,int count,FILE*fp);从buffer开始,一次输出size个字节,重复count次,并将输出的数据存放到fp所指向的文件中;同时,将读写位置指针向前移动size*count个字节。如果调用fread()或fwrite()成功,则函数返回值等于count。fread()和fwrite()函数,一般用于二进制文件二进制文件。返回返回9.3.4 9.3.4 格式化读格式化读/写写fscanf()fscanf()和和fprintf()fprintf()函数函数与scanf()和printf()功能相似,区别在于:操作对象不同:scanf()和prin
20、tf():标准输入(stdin)输出(stdout)文件。fscanf()和fprintf():指定文件。int fscanf(文件指针,格式符,输入变量首地址表);int fprintf(文件指针,格式符,输出表达式表);例如:int i=3;float f=9.80;.fprintf(fp,%2d,%6.2f,i,f);.fprintf()函数的作用是,将变量i按%2d格式、变量f按%6.2f格式,以逗号作分隔符,输出到fp所指向的文件中:3,9.80(表示1个空格)。返回返回9.3.5 9.3.5 读写函数的选用原则读写函数的选用原则从功能角度来说,fread()和fwrite()函数可
21、以完成对文件的任何操作。为方便起见,依下列原则选用:1读/写1个字符个字符(或字节):选用fgetc()和fputc()。2读/写1个个字符串串:选用fgets()和fputs()。3读/写1个(或多个)不含格式不含格式的数据:选用fread()和fwrite()。4读/写1个(或多个)含格式含格式的数据:选用fscanf()和fprintf()。返回返回9.4 9.4 位置指针与文件定位位置指针与文件定位每个文件都有一个读读/写位置指针写位置指针,指向当前读写位置。每次读读/写写后,系统自动自动将位置指针移动到下一个下一个读/写位置上。如果想改变系统这种读写规律,可使用文件定位函数。9.4.
22、1 9.4.1 位置指针复位函数位置指针复位函数rewind()rewind()1用法:int rewind(文件指针文件指针);2功能:使文件的位置指针返回到文件头文件头。9.4.29.4.2*随机读写与随机读写与fseek()fseek()函数函数对于流式文件,既可以顺序读写,也可随机读写,关键在于控制文件的位置指针。顺序读写顺序读写:读写完当前数据后,系统自动将文件的位置指针,移动到下一个读写位置上。随机读写随机读写:读写完当前数据后,通过fseek()函数,将位置指针移动到文件中的任何一个地方。1用法:int fseek(文件指针,位移量,参照点文件指针,位移量,参照点);2功能:将指
23、定文件的位置指针位置指针,从参照点参照点开始,移动指定的位移量位移量。(1)参照点参照点:用0(文件头)、1(当前位置)和2(文件尾)表示。在ANSI C标准中,还规定如下符号常量:SEEK_SET文件头,SEEK_CUR当前位置,SEEK_END文件尾(2)位移量位移量:以参照点参照点为起点,向前(位移量)或后(位移量)移动的字节数。在ANSI C标准中,要求位移量为long int数据。假设文件的当前位置指针指向50(从0 0开始编号),则:fseek(fp,10,0):将位置指针移动到10;fseek(fp,10,1):将位置指针移动到60。实际应用建议实际应用建议:最好使用文件头文件头
24、作为参照点。9.4.3 9.4.3 返回文件当前位置的函数返回文件当前位置的函数ftell()ftell()文件的位置指针可任意移动,也经常移动,往往容易迷失当前位置,ftell()就可以解决这个问题。1用法:long ftell(文件指针文件指针);2功能:返回文件位置指针的当前位置(用相对于文件头文件头的位移量表示)。如果返回值为-1L,则表明调用出错。例如:offset=ftell(fp);if(offset=-1L)printf(“ftell()errorn”);返回返回9.5 9.5 出错检测出错检测9.5.1 ferror()9.5.1 ferror()函数函数在调用I/O库函数时
25、,如果出错,除函数返回值函数返回值有所反映外,也可利用ferror()函数来检测。1用法:int ferror(文件指针文件指针);2功能:返回0未出错;返回非0出错。(1)每次调用I/O函数,均产生一个新的ferror()值,所以应立即检测,否则出错信息会丢失。(2)在执行fopen()函数时,系统将ferror()的值自动置为0。9.5.2 clearerr()9.5.2 clearerr()函数函数1用法:void clearerr(文件指针文件指针);2功能:将ferror()和feof()函数值置为0。对同一文件,只要出错就一直保留,直至遇到clearerr()函数或rewind()函数,或其它任何一个输入输出库函数。返回返回本本 章章 小小 结结1 重点掌握以下11个库函数:fopen()fgetc()、fputc()fgets()、fputs()fread()、fwrite()fscanf()、fprintf()feof(),fseek()2 程序可靠性可靠性和人机交互性人机交互性衡量程序质量的2个重要指标自动校验自动校验输入数据是否正确,判断判断文件操作是否成功,并进行相应提示提示和处理,可有效地提高程序的可靠性和人机交互性。返回返回