《c语言学习c语言课件第12章.ppt》由会员分享,可在线阅读,更多相关《c语言学习c语言课件第12章.ppt(42页珍藏版)》请在三一文库上搜索。
1、第12章 文 件,本章学习目标 了解文件的概念。 熟练掌握文件类型指针的使用。 掌握文件的基本操作。,Return,在程序运行时,程序本身和数据一般都存放在内存中。当程序运行结束后,存放在内存中的数据被释放。 如果需要长期保存程序运行所需的原始数据,或程序运行产生的结果,就必须以文件形式存储到外部存储介质上。 12.1 语言文件概述 12.2 文件的打开与关闭 12.3 文件的读写 12.4 文件定位 12.5 文件的出错检测,12.1 语言文件概述,1文件与文件名 文件是指存放在外部存储介质上的数据集合。 为标识一个文件,每个文件都必须有一个文件名,其一般结构为:主文件名.扩展名 文件命名规
2、则,遵循操作系统的约定。 2文件分类 可以从不同的角度对文件进行分类: (1)根据文件的内容,可分为程序文件和数据文件,程序文件又可分为源文件、目标文件和可执行文件。 (2)根据文件的组织形式,可分为顺序存取文件和随机存取文件。,12.1.1 文件的概念及分类,(3)根据文件的存储形式,可分为ASCII码文件和二进制文件。 ASCII码文件的每1个字节存储1个字符,因而便于对字符进行逐个处理。但一般占用存储空间较多,而且要花费转换时间(二进制与ASCII码之间的转换)。 二进制文件是把内存中的数据,原样输出到磁盘文件中。可以节省存储空间和转换时间,但1个字节并不对应1个字符,不能直接输出字符形
3、式。,12.1.2 文件的操作流程,通过程序对文件进行操作,达到从文件中读数据或向文件中写数据的目的,涉及到的操作有:建立文件、打开文件、从文件中读数或向文件中写数、关闭文件等。一般遵循的步骤为: (1)建立/打开文件 (2)从文件读取数据或向文件写数据。 (3)关闭文件,打开文件是进行文件读写操作之前的必要步骤。打开文件就是将指定的文件与程序联系起来,为下面进行的文件读写做好准备。当为进行写操作而打开一个文件时,如果这个文件不存在,则系统会建立这个文件,并打开它。当为进行读操作而打开一个文件时,文件应该是已经存在的,否则会出错。 所谓读文件是指,将磁盘文件中的数据传送到计算机内存的操作。 所
4、谓写文件是指,从计算机内存向磁盘文件中传送数据的操作。 关闭文件就是取消程序与指定的数据文件之间的联系,表示文件操作的结束。,所谓缓冲文件系统是指,系统自动地在内存区为每个正在使用的文件开辟一个缓冲区。 从内存向磁盘输出数据时,必须首先输出到缓冲区中。待缓冲区装满后,再一起输出到磁盘文件中。 从磁盘文件向内存读入数据时,则正好相反:首先将一批数据读入到缓冲区中,再从缓冲区中将数据逐个送到程序数据区。,12.1.3 缓冲文件系统与非缓冲文件系统,1. 缓冲文件系统,所谓“非缓冲文件系统”是指系统不自动开辟确定大小的缓冲区,而由程序为每个文件设定缓冲区。非缓冲文件系统依赖于操作系统,通过操作系统的
5、功能对文件进行读写,是系统级的输入输出,它不设文件结构体指针,只能读写二进制文件,但效率高、速度快。 在过去使用的C版本(如UNIX系统下使用的C)支持上述两种对文件处理的方法,但是 ANSI C 标准不再包括非缓冲文件系统,因此建议大家最好不要选择它。,2.非缓冲文件系统,12.1.4 文件指针,ANSI C为每个被使用的文件在内存开辟一块用于存放上述信息的小区,利用一个结构体类型的变量存放。该变量的结构体类型由系统取名为FILE,在头文件stdio.h中定义如下:,typedef struct short level; /*缓冲区“满”或“空”的程度*/ unsigned flages;
6、/*文件状态标志*/ char fd; /*文件描述符*/ unsigned char hold; /*如无缓冲区不读取字符*/ short bsize; /*缓冲区的大小*/ unsigned char *baffer; /*缓冲区的读写位置*/ unsigned char *curp; /*文件读写位置*/ unsigned istemp; /*临时文件,指示器*/ short token; /*用于有效性的检查*/ FILE;,在操作文件以前,应先定义文件类型的指针,定义的一般格式: FILE *指针变量标识符 例如: FILE *fp1,*fp2; 按照上面的定义,fp1和fp2均为指
7、向结构体类型的指针变量,分别指向一个可操作的文件,换句话说,一个文件有一个文件类型指针,今后对文件的访问,会转化为针对文件类型指针的操作。,12.2 文件的打开与关闭,12.2.1 文件的打开fopen()函数 1用法:FILE *fopen(“文件名”,“操作方式”); 2功能:返回一个指向指定文件的指针。 3函数原型:stdio.h 。 注:对文件操作的库函数,函数原型均在头文件stdio.h中。后续函数不再赘述。,对文件进行操作之前,必须先打开该文件;使用结束后,应立即关闭,以免数据丢失。 语言规定了标准输入输出函数库,用fopen()函数打开一个文件,用fclose()函数关闭一个文件
8、。,(1)“文件名”是指要打开(或创建)的文件名。如果使用字符数组(或字符指针),则不使用双引号。 (2)“操作方式”如表12-2所示。 例如,FILE *fp; fpfopen(“data.99“,“r“); 3说明 (1)如果不能实现打开指定文件的操作,则fopen()函数返回一个空指针NULL (其值在头文件stdio.h中被定义为)。 为增强程序的可靠性,常用下面的方法打开一个文件: if(fp=fopen(“文件名“,“操作方式“)=NULL) printf(“can not open this filen“); exit(0); ,关于exit()函数 1)用法:void exit
9、(程序状态值); 2)功能:关闭已打开的所有文件,结束程序运行,返回操作系统,并将“程序状态值”返回给操作系统。当“程序状态值”为时,表示程序正常退出;非值时,表示程序出错退出。,(2)“r(b)+”与“a(b)+”的区别:使用前者打开文件时,读写位置指针指向文件头;使用后者时,读写指针指向文件尾。 (3)使用文本文件向计算机系统输入数据时,系统自动将回车换行符转换成一个换行符;在输出时,将换行符转换成回车和换行两个字符。,使用二进制文件时,内存中的数据形式与数据文件中的形式完全一样,就不再进行转换。 (4)有些编译系统,可能并不完全提供上述对文件的操作方式,或采用的表示符号不同,请注意所使用
10、系统的规定。 (5)在程序开始运行时,系统自动打开三个标准文件,并分别定义了文件指针: 1)标准输入文件stdin:指向终端输入(一般为键盘)。如果程序中指定要从stdin所指的文件输入数据,就是从终端键盘上输入数据。,2)标准输出文件stdout:指向终端输出(一般为显示器)。 3)标准错误文件stderr:指向终端标准错误输出(一般为显示器)。 12.2.2 文件的关闭fclose()函数 1用法: int fclose(FILE *文件指针); 2功能:关闭“文件指针”所指向的文件。如果正常关闭了文件,则函数返回值为;否则,返回值为非。 例如,fclose(fp);/*关闭fp所指向的文
11、件*/,12.3 文件的读写,文件打开之后,就可以对它进行读与写的操作了。下面按文件的性质分类进行操作。针对文本文件和二进制文件的不同性质,对文本文件来说,可按字符读写或按字符串读写;对二进制文件来说,可进行成块的读写或格式化的读写。,12.3.1 读写一个字符,C提供fgetc和fputc函数对文本文件进行字符的读写。,读字符函数fgetc fgetc()函数的原型存于stdio.h头文件中,格式为: int fgetc(FILE *fp);,功能:从指定的文件中读一个字符,并将文件的位置指针移到下一个字符处,如果已到文件尾,函数返回EOF。,fgetc()函数调用形式为: 字符变量fget
12、c(文件指针); 例如: ch=fgetc(fp);/*从fp指向的文件中读取一个字符送入ch变量中*/,2. 写字符函数fputc,fputc()函数的原型为: int fputc(int ch,FILE *fp) 功能:将字符ch的值写入所指定文件的当前位置处,并将文件指针后移一位。fputc()函数的返回值是所写入字符的值,出错时返回EOF。,函数的调用形式: fputc(字符,文件指针); 例如: fputc(a,fp);/*将字符常量a写入fp所指向的文件中*/,【例12-1】将存放于磁盘的指定文本文件按读写字符方式逐个地从文件读出,然后再将其显示到屏幕上。(采用带参数的main()
13、,指定的磁盘文件名由命令行方式通过键盘给定。),/*exam12_1*/ #include “stdio.h“ #include “stdlib.h“ int main(int argc, char *argv) char ch; FILE *fp; int i; (续),if(argc=1) printf(“too few parameters.”);exit(0); /*若忘记输入文件名则提示*/ if(fp=fopen(argv1,“r“)=NULL) /*打开一个由argv1所指的文件*/ printf(“not open“); exit(0); while (ch=fgetc(fp)
14、!=EOF) /* 从文件读一字符,显示到屏幕*/ putchar(ch); fclose(fp); return 0; ,演示,注意:在编译连接后在DOS命令方式下执行程序,并要在可执行文件名后输入目标文本文件的完整路径。,【例12-2】从键盘输入字符,存到磁盘文件test.txt中。,/*exam12_2*/ #include “stdio.h“ #include “stdlib.h“ int main(void) FILE *fp; /*定义文件指针*/ char ch; if(fp=fopen(“test.txt“,“w“)=NULL) /*以只写方式打开文件*/ printf(“ca
15、nnot open file!n“); exit(0) ; while (ch=fgetchar()!=n)/*只要输入字符非回车符* / fputc(ch,fp); /*写入文件一个字符* / fclose(fp); return 0; ,演示,程序运行结果: I love china! (运行后从键盘输入) 为了验证从键盘输入的字符是否写入了文件,我们可以在DOS操作系统环境下,利用type命令显示test.txt文件的内容。假设当前路径是c:tc,则输入以下命令: c:tctype test.txt I love china! (显示内容) 说明从键盘写入的字符已存入文件test.txt
16、中。,注意:应转入当前路径后使用type命令,这里假设当前路径是c:tc。,可以执行“file”菜单的“OS Shell”菜单项暂时转入DOS命令行方式。,2.3.2 读写一个字符串,C语言提供fgets()和fputs()函数来实现对文件以字符为单位进行读写,由于这两个函数在使用中往往是一次读写一行,所以也称行读写函数。,1. 读字符串函数fgets,C提供读字符串的函数原型在stdio.h头文件中,其函数形式为: char *fgets(char *str,int num,FILE *fp) fgets() 函数的调用形式为: fgets(字符数组名,n,文件指针); 功能: 从文件指针所
17、指向的文件中读取至多n-1个字符,在读入的最后一个字符后加上串结束标志0,并把它们放入字符数组中。读取过程中如果遇到了换行符或EOF(文件结束符),则读取结束。,【例12-3】从test.txt文件中读入一个含10个字符的字符串。,/*exam12_3*/ #include “stdio.h“ #include “stdlib.h“ int main(void) FILE *fp; /*定义文件指针*/ char str11; if(fp=fopen(“test.txt“,“r“)=NULL)/*以只读方式打开文件*/ printf(“cannot open file!n“); exit(0)
18、 ; fgets(str,11,fp); printf(“n%sn”,str); /*将字符串输出到屏幕*/ fclose(fp); return 0; ,演示,注意:编译时使用“change dir”命令修改工作目录为test.txt所在目录。,2. 写字符串函数fputs,C提供写字符串的函数原型在stdio.h头文件中,其函数形式为: int fputs(char *str,FILE *fp) 其调用的一般形式为: fputs(字符串,文件指针); 功能:将字符串写入文件指针所指向的文件。操作成功时,函数返回0值,失败返回非零值。,【例12-4】写入多个字符串到磁盘文本文件test.tx
19、t。,/*exam12_4*/ #include “stdio.h“ #include “stdlib.h“ #include “string.h“ int main(void) FILE *fp; char str128; if(fp=fopen(“test.txt“,“w“)=NULL) /*打开只写的文本文件*/ printf(“cannot open file!“); exit(0); (续),可以写出test.txt的绝对路径,如:c:examplestest.txt。,while(strlen(gets(str)!=0) /*若串长度为零,则结束*/ fputs(str,fp);
20、/*写入串*/ fputs(“n“,fp); /*写入回车符* / fclose(fp); /*关文件* / return 0; ,Hello! How do you do Good-bye! ,c:tctype test.txt Hello! How do you do Good-bye!,运行后输入,用type命令验证结果,注意:应转入当前路径后使用type命令。,演示,12.3.3 读写一个数据块fread()和fwrite(),实际应用中,常常要求1次读写1个数据块。为此,ANSI C 标准设置了 fread( ) 和fwrite()函数。 1用法: int fread(void *b
21、uffer,int size,int count,FILE *fp); int fwrite(void *buffer,int size,int count,FILE *fp); 2功能: fread()从fp所指向文件的当前位置开始,一次读入size个字节,重复count次,并将读入的数据存放到从buffer开始的内存中;同时,将读写位置指针向前移动size*count个字节。 其中,buffer是存放读入数据的起始地址(即存放何处)。,fwrite()从buffer开始,一次输出size个字节,重复count次, 并将输出的数据存放到fp所指向的文件中;同时,将读写位置指针向前移动size
22、* count个字节。 其中,buffer是要输出数据在内存中的起始地址(即从何处开始输出)。 如果调用fread()或fwrite()成功,则函数返回值等于count。 fread()和fwrite()函数,一般用于二进制文件的处理。,【例12-5】向磁盘写入格式化数据,再从该文件读出显示到屏幕。,/*exam12_5*/ #include “stdio.h“ #include “stdlib.h“ int main(void) FILE *fp1; int i; struct stu /*定义结构体*/ char name15; char num6; float score2; stude
23、nt; if (fp1=fopen(“test.txt“,“wb“)=NULL) /*以二进制只写方式打开文件*/ printf(“cannot open file“); exit(0); (续),printf(“input data:n“); for( i=0;i2;i+) scanf(“%s %s %f %f“,student.name,student.num, (续),printf(“output from file:n“); for (i=0;i2;i+) fread( ,input data: xiaowan j001 87.5 98.4 xiaoli j002 99.5 89.6
24、,output from file: xiaowan j001 87.50 98.40 xiaoli j002 99.50 89.60,运行情况:,演示,12.3.4 对文件进行格式化读写,前面的程序设计中,我们介绍过利用scanf()和printf()函数从键盘格式化输入及在显示器上进行格式化输出。对文件的格式化读写就是在上述函数的前面加一个字母f成为fscanf()和fprintf()。其函数原型为: int fscanf(FILE *stream,char *format,arg_list) int fprintf(FILE *stream,char *format,arg_list)
25、这两个函数的一般调用形式为: fscanf( 文件指针,格式控制串,输入地址表列); fprintf(文件指针,格式控制串,输出表列); 在使用上与标准的输入输出函数相同,只是fscanf()和fprintf()的输入输出是对文件进行。其实scanf()和printf()从广义上讲也是对文件进行,操作对象是对标准输入(stdin)输出(stdout)文件。,【例12-6】将一些格式化的数据写入文本文件,再从该文件中以格式化方法读出显示到屏幕上,其格式化数据是两个学生记录,包括姓名、学号、两科成绩。,/*exam12_6*/ #include “stdio.h“ #include “stdlib
26、.h“ int main(void) FILE *fp; int i; struct stu /*定义结构体类型*/ char name15; char num6; float score2; student; /*说明结构体变量*/ (续),if (fp=fopen(“test.txt“,“w“)=NULL) /*以文本只写方式打开文件*/ printf(“cannot open file“); exit(0); printf(“input data:n“); for( i=0;i2;i+) scanf(“%s %s %f %f“,student.name,student.num, /* 写
27、入文件*/ (续),fclose(fp); /*关闭文件*/ if (fp=fopen(“test.txt“,“r“)=NULL) /*以文本只读方式重新打开文件*/ printf(“cannot open file“); exit(0); printf(“output from file:n“); while(fscanf(fp,“%s %s %f %fn“,student.name, student.num, ,演示,12.3.5 读写函数的选用原则,从功能角度来说,fread()和fwrite()函数可以完成文件的任何数据读写操作。 但为方便起见,依下列原则选用: 1读/写1个字符(或字
28、节)数据时:选用fgetc()和fputc()函数。 2读/写1个字符串时:选用fgets()和fputs()函数。 3读/写1个(或多个)不含格式的数据时:选用fread()和fwrite()函数。 4读/写1个(或多个)含格式的数据时:选用fscanf()和fprintf()函数。,12.4 文件定位,文件中有一个读写位置指针,指向当前的读写位置。每次读写1个(或1组)数据后,系统自动将位置指针移动到下一个读写位置上。 如果想改变系统这种读写规律,可使用有关文件定位的函数。 12.4.1 位置指针复位函数rewind() 1用法:int rewind(文件指针); 2功能:使文件的位置指针
29、返回到文件头。 12.4.2 随机读写与fseek()函数 对于流式文件,既可以顺序读写,也可随机读写,关键在于控制文件的位置指针。 所谓顺序读写是指,读写完当前数据后,系统自动将文件的位置指针移动到下一个读写位置上。,所谓随机读写是指,读写完当前数据后,可通过调用fseek()函数,将位置指针移动到文件中任何一个地方。 1用法:int fseek(文件指针,位移量,参照点); 2功能:将指定文件的位置指针,从参照点开始,移动指定的字节数。 (1)参照点:用0(文件头)、1(当前位置)和(文件尾)表示。 在ANSI C标准中,还规定了下面的名字: SEEK_SET文件头, SEEK_CUR当前
30、位置, SEEK_END文件尾 (2)位移量:以参照点为起点,向前(当位移量时)或后(当位移量时)移动的字节数。在ANSI C标准中,要求位移量为long int型数据。 fseek()函数一般用于二进制文件。,12.4.3 返回文件当前位置的函数ftell() 由于文件的位置指针可以任意移动,也经常移动,往往容易迷失当前位置,ftell()就可以解决这个问题。 1用法:long ftell(文件指针); 2功能:返回文件位置指针的当前位置(用相对于文件头的位移量表示)。 如果返回值为-1L,则表明调用出错。例如: offset=ftell(fp); if(offset= =-1L)print
31、f(“ftell() errorn”);,12.5 出错检测,12.5.1 ferror()函数 在调用输入输出库函数时,如果出错,除了函数返回值有所反映外,也可利用ferror()函数来检测。 1用法: int ferror(文件指针); 2功能:如果函数返回值为0,表示未出错;如果返回一个非0值,表示出错。 (1)对同一文件,每次调用输入输出函数均产生一个新的ferror()函数值。因此在调用了输入输出函数后,应立即检测,否则出错信息会丢失。 (2)在执行fopen()函数时,系统将ferror()的值自动置为0。,12.5.2 clearerr()函数 1用法: void clearerr(文件指针); 2功能:将文件错误标志(即ferror()函数的值)和文件结束标志(即feof()函数的值)置为0。 对同一文件,只要出错就一直保留,直至遇到clearerr()函数或rewind()函数,或其它任何一个输入输出库函数。,作业与实验 作业:习题十二? 上机操作:实验十二,Return,
链接地址:https://www.31doc.com/p-2102432.html