第十三章本章要点文件的基本概念文件的基本函数文件的顺序读写文件的随机读写文件的简单应用主要内容13.1C文件的有关概念13.2文件的打开与关闭13.3文件的顺序读写13.4文件的随机读写13.5文件读写的出错检测§13.1C文件的有关概念13.1.1什么是文件所谓文件一般指存储在外部介质(如磁盘磁带)上数据的集合.操作系统是以文件为单位对数据进行管理的.输入输出是数据传送的过程,数据如流水一样从一处流向另一处,因此常将输入输出形象地称为流(stream),即输入输出流。C语言把文件看作是一个字符(字节)的序列,即由一个一个字符(字节)的数据顺序组成。一个输入输出流就是一个字节流或二进制流。§13.1C文件的有关概念13.1.2文件名一个文件要有一个惟一的文件标识,以便用户识别和引用。文件标识包括三部分:(1)文件路径:(2)文件名主干;(3)文件后缀。文件路径表示文件在外部存储设备中的位置。如:d:\cc\temp\file1.dat↑↑↑文件路径文件名主干文件后缀注意:•文件标识被称为文件名,但此时的文件名包括以上三部分内容,而不仅是文件名主干。•文件名主干的命名规则遵循标识符的命名规则。后缀用来表示文件的性质,一般不超过3个字母.如:.doc(Word生成的文件),.txt(文本文件),.dat(数据文件)13.1.3文件的分类根据数据的组织形式,数据文件可分为ASCII文件和二进制文件。ASCII文件(文本文件):每一个字节放一个ASCII代码二进制文件:把内存中的数据按其在内存中的存储形式原样输出到磁盘上存放.例:整数13000在内存中的存储形式以及分别按ASCII码形式和二进制形式输出如下图所示:§13.1C文件的有关概念§13.1C文件的有关概念13.1.3文件的分类ASCII文件和二进制文件的比较:ASCII文件便于对字符进行逐个处理,也便于输出字符。但一般占存储空间较多,而且要花费转换时间。二进制文件可以节省外存空间和转换时间,但一个字节并不对应一个字符,不能直接输出字符形式。一般中间结果数据需要暂时保存在外存上,以后又需要输入内存的,常用二进制文件保存。§13.1C文件的有关概念13.1.4文件缓冲区ANSIC标准采用“缓冲文件系统”处理文件.缓冲文件系统:系统自动地在内存区为每一个正在使用的文件开辟一个缓冲区。从内存向磁盘输出数据必须先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘去。文件程序数据区输出文件缓冲区输入文件缓冲区§13.1C文件的有关概念13.1.5文件指针不同的C编译系统的FILE类型包含的内容不完全相同,但大同小异。TurboC在stdio.h文件中有以下的文件类型声明:typedefstruct{shortlevel;/*缓冲区“满”或“空”的程度*/unsignedflags;/*文件状态标志*/charfd;/*文件描述符*/unsignedcharhold;/*如无缓冲区不读取字符*/shortbsize;/*缓冲区的大小*/unsignedchar*buffer;/*数据缓冲区的位置*/unsignedar*curp;/*指针,当前的指向*/unsignedistemp;/*临时文件,指示器*/shorttoken;/*用于有效性检查*/}FILE;在缓冲文件系统中,每个被使用的文件都要在内存中开辟一FILE类型的区,存放文件的有关信息.§13.1C文件的有关概念13.1.5文件指针FILE类型的数组:FILEf[5];定义了一个结构体数组f,它有5个元素,可以用来存放5个文件的信息。文件型指针变量:FILE*fp;fp是一个指向FILE类型结构体的指针变量。可以使fp指向某一个文件的结构体变量,从而通过该结构体变量中的文件信息能够访问该文件。如果有n个文件,一般应设n个指针变量,使它们分别指向n个文件,以实现对文件的访问。§13.1C文件的有关概念13.1.5文件指针在标准输入输出库中,系统定义了三个FILE型的指针变量:1.stdin(标准输入文件指针)。指向在内存中与键盘相应的文件信息区,因此,用它进行输入就蕴含了从键盘输入。2.stdout(标准输出文件指针)。指向在内存中与显示器屏幕相应的文件信息区,因此,用它进行输出就蕴含了输出到显示器屏幕。3.stderr(标准错误文件指针),用来输出出错的信息,它也指向在内存中与显示器屏幕相应的文件信息区,因此,在程序运行时的出错的信息就输出到显示器屏幕。§13.1C文件的有关概念13.1.6文件的位置指针位置指针用来指示当前的读写位置。一般情况下,在对字符文件进行顺序读写时,文件的位置指针指向文件开头,这时如果对文件进行读的操作,就读第一个字符,然后文件的位置指针顺序向后移一个位置,在下一次执行读的操作时,就将指针指向的第二个字符读入。依此类推,直到遇文件尾.↑↑↑文件头读写当前位置文件尾有时希望在一个文件的原有数据之后再添加新的数据,应该把文件位置指针移到文件尾,然后再接着写入新的数据,这就是文件的追加。§13.2文件的打开与关闭13.2.1文件的打开(fopen函数)函数调用:FILE*fp;fp=fopen(文件名,使用文件方式);①需要打开的文件名,也就是准备访问的文件的名字;②使用文件的方式(“读”还是“写”等);③让哪一个指针变量指向被打开的文件。§13.2文件的打开与关闭13.2.1文件的打开(fopen函数)文件使用方式含义“r”(只读)为输入打开一个文本文件“w”(只写)为输出打开一个文本文件“a”(追加)向文本文件尾增加数据“rb”(只读)为输入打开一个二进制文件“wb”(只写)为输出打开一个二进制文件ab“(追加)向二进制文件尾增加数据r+“(读写)为读/写打开一个文本文件w+”(读写)为读/写建立一个新的文本文件a+”(读写)为读/写打开一个文本文件rb+“(读写)为读/写打开一个二进制文件“wb+“(读写)为读/写建立一个新的二进制文件“ab+”(读写)为读/写打开一个二进制文件§13.2文件的打开与关闭13.2.2文件的关闭(fclose函数)函数调用:fclose(文件指针);函数功能:使文件指针变量不指向该文件,也就是文件指针变量与文件“脱钩”,此后不能再通过该指针对原来与其相联系的文件进行读写操作返回值:关闭成功返回值为0;否则返回EOF(-1)§13.3文件的顺序读写13.3.1向文件读写一个字符1.用fputc函数向文件写入一个字符.调用形式:fputc(ch,fp);函数功能:将字符(ch的值)输出到fp所指向的文件中去。返回值:如果输出成功,则返回值就是输出的字符;如果输出失败,则返回一个EOF.§13.3文件的顺序读写13.3.1向文件读写一个字符2.fgetc函数从文件读入一个字符.调用形式:ch=fgetc(fp);函数功能:fgetc函数带回一个字符,赋给ch。返回值:如果在执行fgetc函数读字符时遇到文件结束符,函数返回一个文件结束标志EOF(即-1)。§13.4文件的读写(续)fputc和fgetc函数使用举例:例13.1从键盘输入一些字符,逐个把它们送到磁盘上去,直到输入一个“#”为止。3.读写字符举例例13.1从键盘输入一些字符,逐个把它们送到磁盘上去,直到输入一个“#”为止。#includestdlib.h#includestdio.hvoidmain(void){FILE*fp;charch,filename[13];scanf(%s,filename);if((fp=fopen(filename,w))==NULL){printf(cannotopenfile\n);exit(0);/*终止程序*/}ch=getchar();/*接收执行scanf语句时最后输入的回车符*/ch=getchar();/*接收输入的第一个字符*/while(ch!='#'{fputc(ch,fp);putchar(ch);ch=getchar();}fclose(fp);}运行情况如下:(输入磁盘文件名)computerandcomputerandc(输出一个字符串)§13.4文件的读写(续)fputc和fgetc函数使用举例:例13.2将一个磁盘文件中的信息复制到另一个磁盘文件中。例13.2将一个磁盘文件中的信息复制到另一个磁盘文件中。#includestdlib.h#includestdio.hmain(){FILE*in,*out;charch,infile[13],outfile[13];printf(Entertheinfilename:\n);scanf(%s,infile);printf(Entertheoutfilename:\n);scanf(%s,outfile);if((in=fopen(infile,r))==NULL){printf(cannotopeninfile\n);exit(0);}if((out=fopen(outfile,w))==NULL){printf(cannotopenoutfile\n);exit(0);}while(!feof(in))fputc(fgetc(in),out);fclose(in);fclose(out);}运行情况如下:Entertheinfilenamefile1.dat(输入原有磁盘文件名Entertheoutfilename:file2.dat(输入新复制的磁盘文件名)程序运行结果是将file1.dat文件中的内容复制到file2.dat中去。§13.3文件的顺序读写13.3.2向文件读写一个字符串fgets函数函数原形char*fgets(char*str,intn,FILE*fp);函数功能:从指定的文件读入一个字符.返回值:若执行fgets函数成功,则返回值为str数组首元素的地址如果一开始就遇到文件尾或读数据出错,则返回NULL§13.3文件的顺序读写13.3.2向文件读写一个字符串fputs函数函数原形intfputs(conststr,FILE*fp);函数功能:用fputs函数可以向指定的文件输出一个字符串.§13.4文件的读写(续)fputc和fgetc函数使用举例:例13.2将一个磁盘文件中的信息复制到另一个磁盘文件中。例13.3从键盘读入若干个字符串,对它们按字母顺序排序,后把它们送到谚磁盘文件中保存.#includestdio.h#includestdlib.h#includestring.hvoidmain(){FILE*fp;charstr[3][13],temp[13];inti,j,k,n=3;printf(Enterstrings:\n);for(i=0;in;i++)gets(str[i]);for(i=0;in-1;i++){k=i;for(j=i+1;jn;j++)if(strcmp(str[k],str[j])0)k=j;§13.4文件的读写(续)fputc和fgetc函数使用举例:例13.2将一个磁盘文件中的信息复制到另一个磁盘文件中。if(k!=i){strcpy(temp,str[i]);strcpy(str[k],strcpy(str[i],str[k]);temp);}}if((fp=fopen(D:\\CC\\temp\\string.dat,w))==NULL){printf(can'topenfile!\n);exit(0);}printf(\nThenewsequence:\n);for(i=0;in;i++){fputs(str[i],fp);fputs(\n,fp);printf(%s\n,str[i]);}}运行情况:Enterstrings:China↙Canada↙India↙Thenewsequence:CanadaChinaIndia§13.3文件的顺序读写13.3.3向文件进行格式化读写函数调用:fprintf(文件指针,格式字符串,输出表列);fscanf(文件指针,