第11章文件本章要点掌握文件的基本概念掌握文件类型指针理解文件操作的基本方法掌握文件处理函数本章难点对文件进行不同操作的函数的功能及其用法11.1C文件概述一、文件的概念文件:是指存储在外部介质上数据的集合。操作系统是以文件为单位对数据进行管理的。每一个与主机相连的输入或输出设备都看作是一个文件。二、文件的存在形式及分类文件的存在形式:文件名+文件内容。文件内容:是一个字符(字节)序列,即由一个个字符(字节)的数据顺序组成。对文件的存取是以字符(字节)为单位的,这类文件称为流式文件。文件的分类:⑴ASCII码文件(文本文件):文件的每一个字节放一个ASCII代码,代表一个字符。⑵二进制文件:把内存中的数据按其在内存中的存储形式原样输出到文件上。根据数据在内存的组织形式不同可分为两类文件∶ASCII码文件(文本文件)二进制文件根据数据读写方式不同可分为两类文件∶顺序存取文件随机存取文件三、文件的基本操作(1)打开文件∶把文件名等目录信息从磁盘上读入内存并存入结构体。⑵关闭文件∶把内存结构体中的文件名等目录信息写入磁盘。(3)写文件∶向文件写内容。(4)读文件∶从文件读内容。四、文件的输入输出方式C语言对文件进行处理分为:非缓冲文件系统缓冲文件系统⑴非缓冲文件系统∶程序与外设直接进行数据交换。特点∶每读写一次都要启动外设。⑵缓冲文件系统∶程序与外设通过内存缓冲区进行数据交换。(常用的方式)特点∶只有内存缓冲区满(写盘)或空(读盘)才启动外设。程序数据区输出文件缓冲区输入文件缓冲区磁盘11.2C文件类型指针一、文件类型(FILE)每个被使用的文件都在内存中开辟一个区,用来存放文件的有关信息(如文件名,状态,当前位置等)。这些信息保存在一个结构体类型的变量中。结构体类型由系统定义为“FILE”。有的C版本在stdio.h文件中有如下定义:typedefstruct{int_fd;;/*文件号*/int_cleft;/*缓冲区中剩下的字符*/int_mode;/*文件操作模式*/char*_nexttc;/*下一个字符位置*/char*_buff;/*文件缓冲区位置*/}FILE;二、定义FILE类型指针变量FILE类型的指针变量定义方法∶FILE*指针变量名;例如:FILE*fp;含义:fp是一个指向FILE类型结构体的指针变量。可以使fp指向某个文件的结构体变量,从而通过该结构体变量中的文件信息能够访问该文件。11.3文件的基本操作一、文件的打开函数(fopen函数)(1)调用方式:FILE*fp;fp=fopen(文件名,文件的使用方式);所要打开的文件名。必须是用双引号引起的字符串常量。具有特定含意的符号也必须由双引号引起用户定义的文件类型指针变量⑵功能:以指定的方式打开指定的文件,若操作成功,则返回一个指向该文件的指针,若打开文件时出现错误,则返回空指针NULL。例∶FILE*fp;fp=fopen(stu.dat,r);⑶文件使用方式•基本方式字符(单独使用是对文本文件):r仅为读而打开。(只读文件)w仅为写而打开。(建立新文件)a仅为添加而打开。(写旧文件)•按二进制格式读写文件(基本方式字符+“b”)∶b辅助说明,按二进制格式读写文件。•同时进行读写文件(基本方式字符+[“b”]+“+”)∶+辅助说明,可同时进行读和写文件。例如:fp=(“stu.dat”,“rb”);例如:fp=(“stu.dat”,“r+”);例:#includestdio.hmain(){FILE*fp;if((fp=fopen(stu.dat,r))==NULL){printf(filenotfound.);exit(0);}else{printf(fileopenedok!);fclose(fp);}}程序运行结果:如果磁盘上存在文件stu.dat,屏幕上会显示fileopenok!,否则屏幕上显示filenotfound.。常使用此方法打开一个文件exit函数的功能是关闭所有文件,终止程序运行。exit(0)为正常终止程序二、文件的关闭函数(fclose函数)(1)调用方式:fclose(文件指针);⑵功能:关闭由文件指针指定的文件,把缓冲区中的数据(未装满缓冲区的数据)输出到磁盘上,释放文件指针。例如:FILE*fp;fp=fopen(“output.dat”,“r+”);……/*进行读写操作*/fclose(fp);注意:fopen函数和fclose函数总是成对出现的。无fclose函数时会导致部分数据丢失!11.4文件的读写函数一、fputc函数和fgetc函数这两个函数是以字符为单位进行文件读写的函数。1.fputc函数一般调用形式:fputc(字符常量或变量,文件指针);功能:把指定字符存入文件指针所指的文件中。如果输出失败,则返回一个EOF(-1)。例如:fputc(ch,fp);(其中ch为字符变量,fp为文件指针)含义:将ch的值输出到fp所指向的文件中去。(EOF是在stdio.h文件中定义的符号常量,值为-1)2.fgetc函数一般调用形式:字符变量=fgetc(文件指针);功能:从文件指针所指文件中读一个字符赋给指定的字符变量。当遇文件结束符,返回一个文件结束标志EOF(-1)。例如:ch=fgetc(fp);其中ch为字符变量,fp为文件指针。含义:从fp所指向的文件中读入一个字符赋给字符变量ch。例:阅读程序。#includestdio.h#defineNULL0main(){FILE*fp;intcount=0;charc;if((fp=fopen(“file.txt”,“r”))==NULL){printf(“Can’tOpenFile\n”);exit(0);}c=fgetc(fp);while(c!=EOF){count++;c=fgetc(fp);}printf(“count=%d\n”,count);fclose(fp);}若文件file.txt的内容是:abcd1234ABCD输出结果:12这是读一个文本文件中字符,并判断文件是否结束的常用方法二、fread函数和fwrite函数一般调用形式:fread(buffer,size,count,fp);fwrite(buffer,size,count,fp);其中:buffer:是一个指针。(是起始地址)。对fread来说,它是读入数据的存放地址。对fwrite来说,它是输出数据的地址。size:要读写的字节数。count:要进行读写多少个size字节的数据项。功能:对fp所指的文件读写buffer所指的size*count个字节数据。例如:fread(f,4,2,fp);(其中f是实型数组名)例1把数组a写入文件fa;再从fa读入数组b。#includestdio.hmain(){FILE*fp;inta[100]={1,5,6,78,21,34,67,87,23},b[100],i;fp=fopen(tmp,wb);fwrite(a,sizeof(a),1,fp);/*fwrite(a,sizeof(int),100,fp);*/fclose(fp);fp=fopen(tmp,rb);fread(b,sizeof(a),1,fp);for(puts(),i=0;i10;i++)printf(%6d,b[i]);fclose(fp);}三、fprintf函数和fscanf函数这两个函数是进行格式读写文件的函数。一般调用形式:fprintf(文件指针,格式字符串,输出表列);fscanf(文件指针,格式字符串,输入表列);例如:fprintf(fp,“%d,%6.2f”,i,x);功能:按指定格式将数据写到指定文件中。或从指定文件按格式输入数据。又如:fscanf(fp,“%d,%f”,&i,&x);四、fputs函数和fgets函数这两个函数是以字符串为单位进行文件读写的函数。一般调用形式:fputs(字符串,文件指针);1.fputs函数功能:向指定文件输出一个字符串。例如:fputs(str,fp);(其中str是字符数组名)含义:向fp所指向的文件中输出str中的字符串。2.fgets函数fgets(字符串,字符串长度,文件指针);功能:从指定文件中读入一个字符串。例如:fgets(str,n,fp);(其中str是字符数组名)含义:从fp指向的文件读取长度为n-1的字符串,最后加一个‘\0’存入字符数组str中。调用形式:11.5文件的定位函数1.rewind函数一般调用形式:rewind(文件指针);功能:使位置指针重新返回文件的开头。2.fseek函数一般调用形式:fseek(文件指针,位移量,起始点);起始点:用0、1、2或其对应的名字SEEK_SET、SEEK_CUR、SEEK_END代替,分别表示文件开始、文件当前位置、文件末尾。位移量:指以起始点为基点,向前(-)或向后移动的字节数。ANSIC标准规定在数字末尾加一个字母L,表示long型。功能:把文件的读写位置指针移到指定的位置。例如:fseek(fp,128L,SEEK_SET);将位置指针移到离文件头128个字节处。例如:fseek(fp,-10L,2);将位置指针从文件末尾处向后退10个字节。注意:fseek函数一般用于二进制文件。3.ftell函数一般调用形式:ftell(文件指针);功能:返回文件位置指针的当前值。例如:pos=ftell(fp);获取fp指向文件的当前读写位置,并将其值赋给变量pos。11.6文件出错检测函数1.ferror()函数ferror()函数用来确定文件操作系统中是否出错。其函数原型为:intferror(FILE*fp);如果ferror()函数返回值为0,则表示此前的文件操作成功;否则,若返回一个非0值,则表示最近一次文件操作出错。由于对文件的每次I/O操作都会形成新的出错码,所以在每次文件操作后应立即调用ferror()函数查看此次操作是否成功,否则会丢失信息。表示上述功能常用的语句的是:if(ferror(fp)){printf(filecannotI/O\n);fclose(fp);exit(0);}2.clearer()函数clearer()函数的函数原型为:voidclearer(FILE*fp);功能是清除文件结束标志和文件出错标志(设置为0)。本函数没有返回值。11.7文件综合实例编写一个程序,从data.dat文本文件中读出一个字符,将其加密后写入data1.dat文件中,加密方式是字符的ASCII码加1。分析:先打开data.dat文本文件并建立data1.dat文件,从前者读出一个字符c,将(c+1)%256这个ASCII码对应的字符写入后者中。直到读完为止。#includestdio.hvoidmain(){FILE*fp,*fp2;charc;if((fp=fopen(data.dat,r))==NULL){printf(不能打开文件\n);return;}if((fp1=fopen(data1.dat),w)==NULL){printf(不能建立文件\n);return;}while(!feof(fp)){c=fgetc(fp);c=(c+1)%256;fputc(c,fp1);}fclose(fp);fclose(fp);}11.8小结(1)文件是指存储在外部介质上的数据集合。(2)对文件的操作包括文件的打开、关闭、读、写、文件的定位和出错的检验等。现在分别介绍如下:①在C语言中使用fopen()函数完成对文件的打开操作。其一般调用方式为:fopen(文件名,操作方式);②关闭文件用函数fclose()函数来实现,其调用的形式为:fclose(fp);③文件的读函数包括fgetc()函数、fgets()函数、fread()函数和fscanf()函数。fgetc()函数的功能是从指定的文件中读入一个字符。fgets()函数的功能是从文件指针所指向的文件中,读入一个字符串。fscan