1、1,第12章 文件,C语言程序设计,华北电力大学计算机科学系 C语言课程组,2,学习目标,什么是文件?C文件是如何存储的 什么是文本文件和二进制文件 如何打开文件、关闭文件 如何进行文件读写操作 如何编写程序,进行外部数据处理,3,12.1 文件概述,问题引入:我们想对文件中保存的100个学生的数据进行成绩统计,如何处理?我们想将一些文字写入文件中,如何处理?C语言中提供文件类型,可以实现对文件的存储访问。,4,【例12-1】将“I am a student!”写入文件f1.txt中,#include #include void main() FILE *fp;if(fp=fopen(“f1.
2、txt”,”w”) = NULL)printf(“File open error!n”);exit(0);fprintf(fp,”%s”,”I am a student!”);if(fclose(fp)printf(“Can not close the file!n”);exit(0); ,定义文件指针,打开文件,关闭文件,写文件,5,12.1.2 文件的概念,文件是指一组相关数据的有序集合。这个数据集有一个名称,叫做文件名。例如源程序文件*.cpp 目标文件*.obj可执行文件*.exe库文件 (头文件)*.h。PDF文件word文件.txt文件,6,文件分类,用户角度分类 1、普通文件前面
3、列举的所有文件 2、设备文件打印机、显示器、键盘等编码方式分类 1、二进制文件:存放二进制编码形式 2、文本文件:存放对应的字符编码,7,二进制文件和文本文件的区别,(1)文本文件占用字节多,把内存中的数据写入文本文件或者从文本文件读数据存放在内存中,需要进行转换,存取速度相对较慢。二进制文件占用字节少,读写操作不需要进行转换,存取速度相对较快。 (2)文本文件可以直接用记事本等查看,如:C的源程序文件;二进制文件不能够直接查看,如C的可执行程序文件。 (3)一般,原始数据和最终运行结果用文本文件,以便查看修改;中间的运行结果采用二进制文件能够提高存取速度。,8,12.1.3 缓冲文件系统,由
4、于磁盘的读写速度要比内存的读写速度慢很多,为了减少等待的时间,在文件的读写过程中,采用内存缓冲区技术。,程序,内存缓冲区,磁盘,9,12.1.4 文件结构与文件指针,文件结构的定义(包含在stdio.h),typedef struct short level; /*文件状态*/unsigned flags; /*文件状态的标识*/char fd; /*文件描述*/short bsize; /*缓冲区大小*/unsigned char *buffer; /*文件缓冲区位置*/unsigned char *curp; /*文件当前读写位置*/unsigned char hold; /*缓冲区剩下的
5、字符*/unsigned istemp; /*临时文件标识*/short token; /*有效性检查*/ FILE;,10,定义文件类型指针的格式为:FILE *fp;fp用来指向文件缓冲区; 用fp可以实现对文件的操作。,11,12.2文件打开与关闭,12.2.1显示文件的内容 【例12-2】 已知一个数据文件f.dat中保存了4个电话号码信息,包括姓名、座机、手机,文件内容如下:源程序如下:,王晓燕 51963578 13641346466 李明 51962543 13535779256 王华 51973325 13933625435 张一 80798222 13503456645,12
6、,#include #include void main() FILE *fp;char name20;char tel10;char mobil20;if(fp=fopen(“d:f.txt“,“r“) = NULL)printf(“File open error!n“); exit(1);while(!feof(fp)fscanf(fp,“%s%s%s“,name,tel,mobil);printf(“%st%st%sn“,name,tel,mobil);if(!fclose(fp)printf(“Can not close the file!n“); exit(1); ,打开文件不成功,
7、关闭文件不成功,没有到文件尾,13,12.2.2打开文件,打开文件由标准函数fopen()实现,其调用的一般形式为: 文件指针名=fopen(“文件名”, “文件打开方式“); 说明: “文件指针名”必须是被说明为FILE 类型的指针变量; 括号内的两个参数“文件名”和“文件打开方式”都是字符串。“文件名”指出要对哪个文件进行操作,必须指出文件的路径,默认为应用程序的当前路径;“文件打开方式”用来确定对所打开的文件进行什么操作。 fopen()函数具有返回值。如果执行成功,函数将返回包含文件缓冲区等信息的FILE结构体地址,赋给文件指针名。否则,返回一个NULL的FILE指针。,14,举例,F
8、ILE *fp; fp=fopen(“file_a“,“r“); 作用:在当前目录下打开文件file_a,并使fp指向该文件;”r”表示只允许进行“读”操作,。FILE *fp; fp=fopen(“c:f1“,“rb“) 作用:打开C驱动器磁盘的根目录下的文件f1;“rb”指定该文件是一个二进制文件,只允许按二进制方式进行读操作。两个反斜线“ ”中的第一个表示转义字符,第二个表示根目录。,15,在打开一个文件时,如果出错,fopen将返回一个空指针值NULL。在程序中可以用这一信息来判别是否完成打开文件的工作,并作相应的处理。因此常用以下程序段打开文件:,if(fp=fopen(“c:f1“
9、,“rb“)=NULL)printf(“nerror on open c:f1“);exit(1);,16,使用文件的方式,17,12.2.3关闭文件,函数调用格式为: Int fclose(文件指针);无错返回0,有错返回非0。,if(fclose(fp)printf(“Can not close file!n“);exit(1);,18,12.3文本文件读写,【12-3】 将键盘键入的字符存入文件中,再将文件中的数据读出显示。#include #include void main() FILE *pf;char c;if(pf = fopen(“f.txt“,“w+“) = NULL)pr
10、intf(“File open error!n“);exit(1);while(c=getchar()!=#)fputc(c,pf);fclose(pf);pf = fopen(“f.txt“,“r“);while(!feof(pf)printf(“%c “,c = fgetc(pf);fclose(pf); ,19,12.3.2字符读写函数fgetc()和fputc(),1.读字符函数fgetc() fgetc()函数的功能是从指定的文件中读一个字符,函数调用的形式为:字符变量=fgetc(文件指针);2.写字符函数fputc() fputc()函数的功能是把一个字符写入指定的文件中,函数调
11、用的形式为: fputc(字符量,文件指针);,20,例12-4假设磁盘D的根目录下有一个ASCLL码文件“f1.dat”,其内容为“I am a student”。编程完成: 显示文件“f1.dat”的内容; 把字符串“You are a worker”写入文“f1.dat”; 再次显示文件“f1.dat”的内容。分析:显示指定的文本文件内容,再写入新内容,必须打开文件并指定文件的使用方式为“r+”,表示对同一个文本文件先读后写。写入的新内容覆盖原有的内容。,21,#include void main() FILE *pf;char *str=“You are a worker.“,c;in
12、t k;char ch;if(pf = fopen(“d:f1.dat“,“r+“) = NULL)printf(“文件不存在n“); exit(0);printf(“原文件为:n“);while(!feof(pf)ch = fgetc(pf); putchar(ch);printf(“n“);,for(int i=0;stri!=0; i+)fputc(stri,pf);printf(“新文件是:“); rewind(pf); while(!feof(pf)ch = fgetc(pf);putchar(ch); printf(“n“);,22,fgetc函数的使用有以下几点说明:,1、在fg
13、etc()函数调用中,读取的文件必须是以读或读写方式打开的。 2、读取字符的结果也可以不向字符变量赋值,例如:fgetc(fp);但是读出的字符不能保存。 3、在文件内部有一个位置指针。用来指向文件的当前读写字节。在文件打开时,该指针总是指向文件的第一个字节。使用fgetc() 函数后,该位置指针将向后移动一个字节。,23,fputc()函数的使用说明,1、被写入的文件可以用写、读写、追加方式打开,用写或读写方式打开一个已存在的文件时将清除原有的文件内容,写入字符从文件首开始。如需保留原有文件内容,希望写入的字符以文件末开始存放,必须以追加方式打开文件。被写入的文件若不存在,则创建该文件。 2
14、、每写入一个字符,文件内部位置指针向后移动一个字节。 3、fputc()函数有一个返回值,如写入成功则返回写入的字符,否则返回一个EOF。可用此来判断写入是否成功。,24,12.3.3字符串读写函数fgets()和fputs(),1. fgets()函数 调用格式: fgets(s,n,fp); 作用:从文本文件中读取字符串,系统自动在读入的字符串最后加一个字符串结束标志0 参数:s可以是内存中存放字符串的首地址n表示从文件中一次读n-1个字符例如:fgets(str,10,fp);从与fp有联系的文件中读不多于9个的字符,存放在数组str中。,25,2.fputs()函数调用格式 fputs
15、(s,fp); 作用:把s写入文件时,字符串s的结束符0不写入文件。 参数:s是要写入的字符串,可以是字符数组名、字符型指针变量或字符串常量;fp是文件指针 返回值:若函数执行成功,则函数返回所写的最后一个字符;否则,函数返回EOF。 例如:char *str = “hello world!” fputs(str,fp);,26,【例12-5】 建立一个文件,将字符串“I am a student”写入文件中,并读出文件内容。另外,用记事本打开文件,验证结果。分析:首先从键盘输入文件名,建立一个新文件,指定文件使用方式为“w”,然后将键盘读入的字符串写入该文件,关闭文件。重新打开该文件并指定文
16、件的使用方式为“r”,用fgets()函数一次从文件中读一串字符并显示在终端上。,27,#include #include main() FILE *fp;char str30;char str130;char filename30; printf(“please input filename:n“);scanf(“%s“,filename);if(fp = fopen(filename,“w“) = NULL)printf(“The file error!“);exit(0);,28,printf(“please input string:n“);scanf(“%s“,str);fputs(str,fp);fclose(fp);if(fp = fopen(filename,“r“) = NULL)printf(“The file error!“);exit(0);printf(“file content is:n“);fgets(str1,30,fp);printf(“%sn“,str1); ,29,