资源描述
,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,语言程序设计,第九章,数据的永久性存储,C,存储设备,第,九,章,数据的永久性存储,内部存储设备,外部部存储设备,9.1,数据的永久性存储,文件是永久性存储设备的最基本存储单位。文件能够大量的、永久性的保存数据信息,并能够通过各种文件操作功能来管理和使用这些数据。,文件概念:文件是指存储在永久性存储设备上的具有名字,(,文件名,),的一组相关数据的集合,通常也被称为磁盘文件。,9.2,文件的组织方式,根据编码方式,文件可以分为两种:一种是文本文件,(ASCII,码文件,),,另一种是二进制文件。,通过,C,语言编程实现对文件的访问时,必须要严格按照文件原有的编码方式及文件存储格式来对文件进行访问操作,才能正确读写文件数据。,9.3,文件的操作,文件操作主要包括读文件和写文件等。,读文件是指从文件中把数据信息读入内存中,以供程序调用;,写文件是指把内存中的数据信息输出到永久性存储设备上的文件中,起到保存数据和实现数据共享的功能。,9.3,文件的操作,头文件,stdio.h,定义了文件结构体类型,FILE,,用来保存文件的文件名、文件的状态和文件当前的读写位置等相关文件信息。,9.3.1,stdio.h,typedef,struct,short,level;,/*,缓冲区满或空的程度 *,/,unsigned,flags;,/*,文件状态标志 *,/,char,fd,;,/*,文件描述符 *,/,unsigned char,hold;,/*,如无缓冲区不读字符 *,/,short,bsize,;,/*,缓冲区的大小 *,/,unsigned char,*buffer;,/*,数据缓冲区的位置 *,/,unsigned char,*,curp,;,/*,文件内位置指针当前的指向 *,/,unsigned,istemp,;,/*,临时文件指示器 *,/,short,token;,/*,用于有效性检查 *,/,FILE,;,9.3,文件的操作,C,语言的文件操作编程时 ,用,FILE,来定义一个文件结构体类型指针变量,(,通常称为文件指针,),,用来指向被访问的文件并通过该文件指针变量来访问文件信息。文件指针定义形式:,9.3.1,stdio.h,FILE,*,fp,;,/*,定义文件结构体类型指针变量 *,/,上面的,C,程序语句定义了一个文件指针,fp,,但,fp,指向哪个文件,目前并不知道,只有通过文件打开函数让,fp,指向某个指定文件,将,fp,与该文件关联起来,才能使用,fp,。,9.3,文件的操作,C,语言是以文件流的形式来对文件进行访问操作的。为了便于对文件流的顺序访问和随机定位访问,在文件内部还有一个位置指针来指向文件的当前读写操作位置,这就是文件结构体,FILE,中的成员指针变量,curp,。,9.3.1,stdio.h,9.3,文件的操作,stdio.h,中关于文件的宏定义,9.3.1,stdio.h,#define,SEEK_SET,0,/*,表征文件头位置*,/,#define,SEEK_CUR,1,/*,表征文件位置指针当前所处位置*,/,#define,SEEK_END,2,/*,表征文件尾位置*,/,#define,EOF,-1,/*,文件结束标识宏常量*,/,9.3,文件的操作,stdio.h,中关于文件的常用函数,9.3.1,stdio.h,函数名,功能说明,函数名,功能说明,fopen,(),打开文件流,fscanf,(),从文件流中按格式读取数据,fclose,(),关闭文件流,fprintf,(),把数据按格式输出到文件流,feof,(),文件结束标识测试,fread,(),从文件流中读取指定大小的数据块,ferror,(),文件访问错误测试,fwrite,(),向文件流中写入指定大小的数据块,fgetc,(),从文件流中读取,(,输入,),一个字符,rewind(),文件内部读写位置指针复位到文件头,fputc,(),写入,(,输出,),一个字符到文件流中,fseek,(),文件内部读写位置指针置为特定位置,fgets,(),从文件流中读一行或指定长度字符串,ftell,(),返回文件内部读写位置指针当前位置,fputs,(),写字符串到文件流中,9.3,文件的操作,9.3.2,文件的打开与关闭,(1),文件打开函数,fopen,(),原 型:,FILE,*,fopen,(,const char,*filename,const char,*mode );,头文件:,#include,功 能:以指定方式打开所指定的文件,参 数:,filename ,文件路径加文件名,,mode ,文件打开方式,返回值:若打开文件成功,则返回文件指针值;否则,返回,NULL,(2),文件关闭函数,fclose,(),原 型:,int,fclose,(,FILE,*stream);,头文件:,#include,功 能:关闭文件,参 数:,stream ,文件指针,返回值:若关闭文件成功,则返回,0,;否则,返回,EOF,9.3,文件的操作,9.3.2,文件的打开与关闭,FILE,*,fp, *,fpBinary,;,fp,=,fopen,(,“c:zwgzwg.txt,r,);,/*,以只读方式打开文本文件 *,/,if,(,NULL,=,fp,),printf,(,Open,text file ,zwg.txt, error!,);,exit,(-1);,fpBinary,=,fopen,(,“c:zwgzwg.bin,rb,+,);,/*,以读,/,写方式打开二进制文件 *,/,if,(,NULL,=,fpBinary,),printf,(,Open,binary file ,zwg.bin, error!,);,exit,(-1);,/*,此处可放置若干文件操作代码 *,/,fclose,(fp,);,/*,关闭文件指针,fp,所指向的文件 *,/,fclose,(fpBinary,);,/*,关闭文件指针,fpBinary,所指向的文件 *,/,9.3,文件的操作,9.3.2,文件的打开与关闭,关于文件的打开方式,文本,文件,二进制,文件,r,rb,w,wb,a,ab,r+,rb,+,或,r+b,w+,wb,+,或,w+b,a+,ab,+,或,a+b,9.3,文件的操作,9.3.3,文件读,/,写函数及与读写相关的函数,文件结束标识测试函数,feof,(),文件操作错误测试函数,ferror,(),字符读,/,写函数,fgetc,(),和,fputc,(),字符串读,/,写函数,fgets,(),和,fputs,(),格式化读,/,写函数,fscanf,(),和,fprintf,(),数据块读,/,写函数,fread,(),和,fwrite,(),9.3,文件的操作,9.3.3,文件读,/,写函数及与读写相关的函数,文件结束标识测试函数,feof,(),原 型:,int,feof,(,FILE,*stream);,头文件:,#include,功 能:文件结束标识符测试,参 数:,stream ,文件指针,返回值:若文件内部读写位置指针正指向文件尾,则返回非,0,值;否则,返回,0,值,if,(!,feof,(fp,),/*,如果没有遇到文件尾则执行操作 *,/,/*,文件读写操作代码 *,/,9.3,文件的操作,9.3.3,文件读,/,写函数及与读写相关的函数,文件操作错误测试函数,ferror,(),原 型:,int,ferror,(,FILE,*stream);,头文件:,#include,功 能:文件操作错误测试,参 数:,stream ,文件指针,返回值:若,出现错误,,则返回非,0,值;否则,返回,0,值,if,(,ferror,(fp,),/*,如果文件读或写出错 *,/,/*,文件读写错误处理程序代码 *,/,9.3,文件的操作,9.3.3,文件读,/,写函数及与读写相关的函数,字符读,/,写函数,fgetc,(),和,fputc,(),原 型:,int,fgetc,(,FILE,*stream);,头文件:,#include,功 能:从文件中读入一个字符,参 数:,stream ,文件指针,返回值:成功执行则返回所读取字符,(,字节,),的整数值;否则,返回,EOF,原 型:,int,fputc,(,int,ch,FILE,*stream);,头文件:,#include,功 能:把字符,ch,写入到文件中,参 数:,ch,字符,,stream ,文件指针,返回值:成功执行则返回所写入字符的整数值;否则,返回,EOF,ch,=,fgetc,(fp,);,/*,从,fp,所指向的文件流读取一个字符,并赋给字符变量,ch,*/,fputc,(ch,fp,);,/*,把字符,ch,写入到文件中 *,/,9.3,文件的操作,9.3.3,文件读,/,写函数及与读写相关的函数,字符串读,/,写函数,fgets,(),和,fputs,(),原 型:,char,*,fgets,(,char,*s,int,n,FILE,*stream);,头文件:,#include,功 能:从文件中读入一个长度为,n-1,的字符串,参 数:,s ,字符串,,n ,要读入的字符串总长度,(,空字符计算在内,),,,stream ,文件指针,返回值:返回字符指针,s,的值,原 型:,int,fputs,(,char,*s,FILE,*stream);,头文件:,#include,功 能:把字符串,s,写入到文件中,参 数:,s ,字符串,,stream ,文件指针,返回值:成功执行则返回一个非负整数值;否则,返回,EOF,9.3,文件的操作,9.3.3,文件读,/,写函数及与读写相关的函数,格式化读,/,写函数,fscanf,(),和,fprintf,(),原 型:,int,fscanf,(,FILE,*stream,const,char,*format, );,头文件:,#include,功 能:文件格式化读取,参 数:,stream ,文件指针,,format ,格式控制字符串,, ,可变数目变量列表,返回值:成功执行则返回所读取的字节数;否则,返回,EOF,原 型:,int,fprintf,(,FILE,*stream,const,char,*format, );,头文件:,#include,功 能:文件格式化输出,参 数:,stream ,文件指针,,format ,格式控制字符串,, ,可变数目变量列表,返回值:成功执行则返回所写入的字节数;否则,返回一负数值,9.3,文件的操作,9.3.3,文件读,/,写函数及与读写相关的函数,数据块读,/,写函数,fread,(),和,fwrite,(),原 型:,size_t,fread,(,void,*buffer,size_t,size,size_t,count,FILE,*stream);,头文件:,#include,功 能:读取文件数据块,参 数:,buffer ,数据存储区指针,,size ,数据项字节数,,count ,数据项数,,stream ,文件指针,返回值:返回实际读取的数据项数,原 型:,size_t,fwrite,(,void,*buffer,size_t,size,size_t,count,FILE,*stream);,头文件:,#include,功 能:写数据块到文件中,参 数:,buffer ,数据存储区指针,,size ,数据项字节数,,count ,数据项数,,stream ,文件指针,返回值:成功执行,则返回值等于,count,;若返回值小于,count,,则说明写数据库出错,9.3,文件的操作,9.3.3,文件读,/,写函数及与读写相关的函数,例,9-1,编程实现把文本文件,hit.txt,另存为新文本文件,hit_new.txt,。,#include,#include,void,main,(,void,),FILE,*,fp, *,fpNew,;,int,nCh,nResult,;,fp,=,fopen,(,hit.txt,r,);,/*,以只读方式打开文件,hit.txt,*/,if,(,NULL,=,fp,),printf,(,Open,file,hit.txt,errorn,);,exit,(-1);,fpNew,=,fopen,(,hit_new.txt,w,);,/*,创建,hit_new.txt,并以只写方式打开 *,/,if,(,NULL,=,fpNew,),printf,(,Create,file,hit_new.txt,errorn,);,exit,(-1);,while,(!,feof,(fp,),/*,未遇到文件尾时循环读写操作 *,/,nCh,=,fgetc,(fp,);,/*,从文件,hit.txt,读取字符 *,/,if,(,EOF,!=,nCh,),nResult,=,fputc,(nCh,fpNew,);,/*,把字符写到文件,hit_new.txt,中 *,/,if(,EOF,=,nResult,),printf,(,Write,character to,hit_new.txt,errorn,);,exit,(-1);,putchar,(nCh,);,fclose,(fp,);,fclose,(fpNew,);,printf,(,nFile,saveas,successfully!n,);,9.3,文件的操作,9.3.3,文件读,/,写函数及与读写相关的函数,例,9-2,把从键盘输入的一个字符串写到文件,hit.txt,中,再从文件中把该字符串读出来显示到屏幕上。,#include,#include,#include,void,main,(,void,),FILE,*,fp,;,char,str81, strNew81, *,pCh,;,int,nResult,nLen,;,fp,=,fopen,(,hit.txt,w+,);,/*,创建文件,hit.txt,并打开 *,/,if,(,NULL,=,fp,),printf,(,Open,file,hit.txt,errorn,);,exit,(-1);,gets,(str,);,/*,获取键盘输入字符串 *,/,nLen,=,strlen,(str,);,/*,计算字符串长度 *,/,nResult,=,fputs,(str,fp,);,/*,把字符串写入文件中 *,/,if,(,EOF,=,nResult,),printf,(,Write,string to,hit.txt,errorn,);,exit,(-1);,printf,(,Write,string to file completelyn,);,fclose,(fp,);,fp,=,fopen,(,hit.txt,r,);,/*,以只读方式重新打开,hit.txt,*/,if,(,NULL,=,fp,),printf,(,Open,file,hit.txt,errorn,);,exit,(-1);,pCh,=,fgets,(strNew, nLen+1,fp,);,/*,从文件中读取字符串 *,/,if,(,NULL,=,pCh,),printf,(,Read,string from,hit.txt,errorn,);,exit,(-1);,puts,(pCh,);,/*,输出字符串到屏幕,此处也可把,pCh,替换成,strNew,*/,fclose,(fp,);,9.3,文件的操作,9.3.3,文件读,/,写函数及与读写相关的函数,例,9-3,从键盘分别输入整数、浮点数、字符、字符串各一个,要求把这些数据按照键盘输入时的格式写到文件,hit.txt,中,然后从文件中把这些数据按原有格式读入并显示到屏幕上。,#include,#include,#include,void,main,(,void,),FILE,*,fp,;,int,nNum,nResult,;,float,fData,;,char,ch, str30;,printf,(,Please,input an integer, a float, a char and a string like this:n,);,printf,(,2008,8.08,B,Olympicnn,);,scanf,(,%d,%f,%c,%s, &,nNum, &,fData, &,ch,str,);,/*,从键盘格式化输入数据 *,/,fp,=,fopen,(,hit.txt,w+,);,/*,新建文本文件 *,/,if,(,NULL,=,fp,) ,printf,(,Open,file,hit.txt,errorn,);,exit,(-1);,nResult,=,fprintf,(fp,%d,%.2f,%c,%s,nNum,fData,ch,str,);,/*,格式化写入文件 *,/,if,(nResult, 0) ,printf,(,Write,formatted data to,hit.txt,errorn,);,exit,(-1);,printf,(,Write,formatted data to file completelyn,);,nNum,= 0;,/*,清空各变量 *,/,fData,= 0.0;,ch,=,0,;,strcpy,(str,);,fseek,(fp, 0L,SEEK_SET,);,/*,把文件内部读写位置指针重新定位到文件头 *,/,nResult,=,fscanf,(fp,%,d,%f,%c,%s, &,nNum, &,fData, &,ch,str,);,/*,从文件格式化读入数据 *,/,if,(,EOF,=,nResult,) ,printf,(,Read,formatted data from,hit.txt,errorn,);,exit,(-1);,printf,(,%d,%.2f,%c,%sn,nNum,fData,ch,str,);,fclose,(fp,);,9.3,文件的操作,9.3.3,文件读,/,写函数及与读写相关的函数,例,9-4,现有内容为“,The 2008 Beijing Olympic Games were truly exceptional Games!”(,共,60,个字符,包括空格字符在内,),的文本文件,hit.txt,,将其加密成一个二进制文件,hit.bin,。加密算法是把从文件中读出的所有字符按其在文件中的排列顺序依次加上数值,059,。,#include,void,main,(,void,),FILE,*stream;,char,list80;,int,i,NumRead,NumWritten,;,if,(stream,=,fopen,(,hit.txt,r,)!=,NULL,),/*,打开文件 *,/,NumRead,=,fread,(list,sizeof(,char,), 60, stream);,/*,从文件中读取,60,个字符 *,/,printf,(,Number,of items read = %,dn,NumRead,);,/*,输出所读取的字符数 *,/,printf,(,Contents,of buffer = %.60sn, list);,/*,输出所读取的字符块 *,/,fclose,(stream,);,else,printf,(,File,could not be openedn,);,if,(stream,=,fopen,(,hit.bin,wb,) !=,NULL,),/*,创建新的二进制文件 *,/,for ( i = 0; i 60; i+ ),listi, = (,char)(listi, + i);,/*,通过字符运算进行简单加密 *,/,NumWritten,=,fwrite,(list,sizeof(,char,), 60, stream);,/*,把加密后的字符块写入文件中 *,/,printf,(,Wrote,%d itemsn,NumWritten,);,/*,输出已写入文件的字符数 *,/,fclose,(stream,);,else,printf,(,File,could not be openedn,);,9.3,文件的操作,9.3.4,文件定位函数,函数,rewind(),函数,fseek,(),函数,ftell,(),9.3,文件的操作,9.3.4,文件定位函数,函数,rewind(),原 型:,void,rewind,(,FILE,*stream);,头文件:,#include,功 能:,把文件内部读写位置指针无条件的重新指向文件头位置,参 数:,stream ,文件指针,返回值:无返回值,9.3,文件的操作,9.3.4,文件定位函数,函数,fseek,(),原 型:,int,fseek,(,FILE,*stream,long,int,offset,int,whence);,头文件:,#include,功 能:,文件内部读写位置指针置为指向一个特定的位置,该位置由函数的调用参数来决定,参 数:,stream ,文件指针,,offset ,偏移量,,whence ,文件内部预定义位置,返回值:成功执行则返回,0,;否则返回非,0,值,9.3,文件的操作,9.3.4,文件定位函数,函数,ftell,(),原 型:,long,int,ftell,(,FILE,*stream);,头文件:,#include,功 能:返回文件内部读写位置指针当前指向位置,参 数:,stream ,文件指针,返回值:成功执行则返回当前位置距离文件头的偏移量,(,字节数,),;否则返回,-1L,9.3,文件的操作,9.3.4,文件定位函数,例,9-5,计算一个二进制文件的大小,(,所占字节数,),,并在屏幕上显示出来。,#include,void,main,(,void,),FILE,*stream;,long,int,lnFileSize,;,if,(stream,=,fopen,(,hit.bin,rb,)!=,NULL,),fseek,(stream, 0L,SEEK_END,);,/*,文件内部读写位置指针指向文件尾 *,/,lnFileSize,=,ftell,(stream,);,/*,求文件尾到文件头的偏移量即文件大小 *,/,printf,(,The,file size of,hit.bin,is %ld bytesn,lnFileSize,);,fclose,(stream,);,else,printf,(,File,could not be openedn,);,9.4,综合应用实例,例,9-6,给学生管理系统添加文件操作功能,包括从文件中读取学生信息记录及保存中间操作结果到文件中。,/*,定义学生信息结构体类型 *,/,typedef,struct,student,int,id;,/*,学号 *,/,float,cLanguage, math,english,;,/* C,语言、数学和英语成绩 *,/,char,name20;,/*,学生姓名 *,/,STUDENT,;,/*,学生信息结构体数据类型别名 *,/,原 型:,int,ReadStuInfo,(,char,*filename,char,*mode,STUDENT,*,stu,int,num);,功 能:从文件中读取学生成绩信息,参 数:,filename ,文件名,,mode ,文件打开方式,,stu,学生结构体数组,,num ,记录数,返回值:执行成功则返回实际读入的记录数,否则返回,-1,原 型:,int,WriteStuInfo,(,char,*filename,char,*mode,STUDENT,*,stu,int,num);,功 能:把学生成绩信息写入到文件中,参 数:,filename ,文件名,,mode ,文件打开方式,,stu,学生结构体数组,,num ,记录数,返回值:执行成功则返回实际写入的记录数,否则返回,-1,(1),读取学生信息的子函数,ReadStuInfo,(),(2),把中间操作结果写入到文件中的子函数,WriteStuInfo,(),int,ReadStuInfo,(,char,*filename,char,*mode,STUDENT,*,stu,int,num),FILE,*,fp,;,int,nNumRead,nRes,;,fp,=,fopen,(filename, mode);,if,(,NULL,!=,fp,),/*,以数据块方式读入指定数目记录 *,/,nNumRead,=,fread,(,void,*),stu,sizeof,(,STUDENT,), num,fp,);,if,(,ferror,(fp,),/*,错误处理 *,/,printf,(,Reading,error!n,);,nRes,= -1;,else,printf,(,There,have read %d student score records.n,nNumRead,);,nRes,=,nNumRead,;,/*,已正确读入的记录数 *,/,fclose,(fp,);,else,printf,(,Cant,open the student information file!n,);,nRes,= -1;,return,nRes,;,int,WriteStuInfo,(,char,*filename,char,*mode,STUDENT,*,stu,int,num),FILE,*,fp,;,int,nNumWritten,nRes,;,fp,=,fopen,(filename, mode);,if,(,NULL,!=,fp,),/*,以数据块形式写入成绩记录 *,/,nNumWritten,=,fwrite,(,void,*),stu,sizeof,(,STUDENT,), num,fp,);,if,(,ferror,(fp,),/*,错误处理 *,/,printf,(,Writing,error!n,);,nRes,= -1;,else,printf,(,Written,%d records successfully!n,nNumWritten,);,nRes,=,nNumWritten,;,/*,以成功写入的记录数 *,/,fclose,(fp,);,else,printf,(,Cant,open the student information file, please try again!n,);,nRes,= -1;,return,nRes,;,The end,
展开阅读全文