《9数据的永久存储--文件程序设计教学教案》由会员分享,可在线阅读,更多相关《9数据的永久存储--文件程序设计教学教案(64页珍藏版)》请在金锄头文库上搜索。
1、福建工程学院 鲍春波,高级语言程序设计,第9章 数据的永久存储 文件程序设计,引言,到现在为止,我们所写的程序,不管是输入的原始数据,还是中间计算结果或最终计算结果,在程序运行结束退出后,就都无影无踪了。 你的原始数据输入之后存储到哪里了呢?,内存中的数据不能永久保存,内存中的数据在程序退出后,就没办法控制它们了,因为它们所占的内存已经被释放。特别当电脑关机后,内存中的数据更是荡然无存了。,本章要解决的问题,建立学生成绩管理系统的文件版,学习目标,文件的概念 文件的组织方式 文本文件与二进制文件 顺序文件与随机文件 文件的操作 文件的定义方法,文件指针 文件的打开方法两种打开方式 各种读写方法
2、 字符读写 字符串读写 行读写(格式化读写) 块读写 文件的定位,分析,把学生信息记录保存到文件中,或者从文件中读取学生信息, 输入输出不是键盘和屏幕了,文件与目录,什么是文件?永久存储数据的介质是各种各样的“盘”,磁盘、光盘、闪盘等,把数据存储到这些盘上,应该是比较复杂的事情。,数据的永久保存,文件 数据库,文件与目录,操作系统有一个重要的组成部分文件管理模块,也称文件系统。 文件系统封装了外存各种介质的特性,让我们可以用一个相同的接口使用不同的外存,这个接口就是“文件”(FILE)。 我们只需要指明要把数据保存成什么格式的,用什么文件名,操作系统就会在外存上寻找一个最佳位置,把数据写进去;
3、 反之,如果我们要从外存储器上读出数据,也只需告诉它数据的文件名,操作系统就会到外存储器上找到该文件所在的位置,把数据读出来。,树形的目录结构是文件系统的事实标准 每个文件都可以被唯一的“绝对路径(Absolute Path)”表示 在DOS/Windows下:D:usershomeworkmain.c 在Unix/Linux下:/users/homework/main.c 相对路径(Relative Path): main.c,文件的存储格式,数据存储为文件是有格式的,不同内容的数据往往有不同的格式。 一般来说一个源程序是可以在一个编辑器中打开看到的,我们能看到的数据文件被认为是一个字符序列
4、,这种存储格式称为文本格式。,数据文件也可以在编辑器中查看,也可以是文本格式 例如100分的成绩,用文本形式存储的就是1、 0、 0这三个字符的ASCII码,即0 x313030。,更常用的是二进制格式存储,它是把数据转换为二进制形式存放 如100作为一个整数转化为对应的二进制编码存储起来即 0 x00000064 二进制格式存储的数据用编辑器打开是看不到它的真实面目的,显示的是“乱码”,文件的分类,文本文件/二进制文件 二进制存储的文件称为二进制文件(binary file)。 文本格式存储的文件叫做文本文件(text file),其扩展名常为txt, c或cpp,dat等 顺序文件/随机文
5、件 按照记录的关键字顺序存放的文件是顺序文件 可以随机存取的文件是随机文件,C语言中的文件,无论什么文件C语言都把它们看成是有序的字节流,C语言文件操作的一般步骤,(1)声明一个FILE *类型的指针变量。 (2)打开(open)一个文件。 (3)对文件进行输入输出(I/O)操作,也称读写(read/write)操作。 (4)关闭(close)打开的文件。,FILE*指针,stdio.h 定义了FILE结构体类型和 还有一组文件操作函数,文件结构体的定义,typedef struct short level; /*缓冲区满或空的程度*/ unsigned flags; /*文件状态标志*/ c
6、har fd; /*文件描述符*/ unsigned char hold; /*如无缓冲区不读字符*/ short bsize; /*缓冲区的大小*/ unsigned char *buffer;/*数据缓冲区的位置*/ unsigned char *curp; /*指针当前的指向*/ unsigned istemp; /*临时文件指示器*/ short token; /*用于有效性检查*/ FILE;,读操作或输入操作是把数据从外存的文件中读到内存 写操作或输出操作是把数据从内存写到外存的文件中。 可以按字符读写 也可以按记录读写 也可以按字节读写,但不是直接读到内存,也不是直接写到外存,A
7、NSI C 的缓冲文件系统,编译器自动地在内存区为每一个正在使用的文件开辟一个文件缓冲区。,程序员只和缓冲区打交道,从内存向磁盘输出数据必须先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘去。 从磁盘向内存输入数据,则从磁盘文件将一批数据先输入到内存缓冲区,装满缓冲区后再从缓冲区逐个地将数据送到程序数据区给程序变量。,缓冲区是内存中的一块区域,要对它进行读写,首先应该获得它的地址,这就是文件指针FILE *,也就是在进行文件操作之前必须先定义一个文件指针,如 FILE *infile,*outfile,*fp; 三个特殊的文件指针: 标准输入(键盘也被认为是一个文件流)stdin, 标准输出(
8、显示器也被认为是一个文件流)stdout, 标准错误(错误输出认为是一个文件流)stderr。,打开文件,设 FILE *fp; ANSI C的打开文件函数fopen为 fp = fopen(“文件名”,文件的打开方式); 如果fopen打开成功,返回一个不为NULL的FILE指针,打开不成功则返回一个NULL指针 其中文件名可以是绝对路径格式或相对路径格式,文本文件的打开方式,“r” :打开一个已存在的文本文件,用于输入。 “w”: 建立一个新的或覆盖一个已存在的文本文件,用于输出。 “a”: 建立一个新文本文件或以追加的方式打开一个已经存在的文本文件,用于输出。,“r+”: 打开一个已经存
9、在的文本文件用于更新(意思是:既可以读又可以写)。 “w+”: 建立一个新的文本文件或覆盖一个已经存在的文本文件,用于更新。“a+”: 建立一个新的文本文件或以追加的方式打开一个已存在的文本文件,用于更新。,二进制文件的打开方式,与文本文件的6种打开方式类似,只需在打开方式字符串中加入一个字符b “rb”、“wb” 、“ab” “rb+”、“wb+” 、“ab+” 其意义与文本文件的打开方式完全相同,注意:,用“w”、“w+”或“wb”、“wb+”方式打开一个文件时,如果文件已经存在,将覆盖已有的文件。,文件关闭,fclose(fp);,典型的文件建立代码(对应4个基本步骤),FILE *fp
10、; if( (fp=fopen(“input.txt”,“r”) ) = NULL) printf(“Cannot open file, strike any key exit ! ”); getch(); exit(1); /文件读写 fclose(fp);,ANSI C的文件操作函数,字符读写函数 int fgetc(FILE *fp); int fputc(int c, FILE *fp); 或者宏 int getc(FILE *fp); int putc(int c, FILE *fp); 每次读写一个字符,例1:写一个程序把一个源程序文件做一个备份,可以把源程序看成是一个字符序列,采
11、用字符读写方式即可实现 FILE *fp; 代码copyfile.c,思考题,用命令行参数提供输入输出文件名,实现文件的拷贝命令 copyfile file1 file2,字符串读写,char *fgets(char *s, int n, FILE *fp); 从文件中读出n-1字符,存到s指向的字符数组中 int fputs(const char *s, FILE *fp);,例2:从文件中读一个含10个字符的字符串,使用fgets(str,11,fp)从fp指向的文件中读出n-1个字符送入字符数组str中, 末尾会自动加上0。 代码fgets.c,例3 在文件中追加一个字符串,使用 fpu
12、ts(“abcd”,fp)函数把字符串abcd写入fp所指的文件之中 代码fputs.c,格式化读写(文本文件),int fscanf(FILE *fp, const char *format, .); int fprintf(FILE *fp, const char *format, .); 按照某种格式对一组数据进行读写,常用于文本文件的读写 不能看出:当fp = stdin 或 stdout时 fscanf和fprintf与scanf和printf完全相同,例4 顺序读写学生信息,struct stu char name10; int num; int age; char addr15;
13、 boya2,boyb2,*pp,*qq; pp=boya; /pp指向了数组boya qq=boyb;,以读写的方式打开一个文本文件,FILE *fp; if(fp=fopen(“stuInfo.txt,w+)=NULL) printf(“Cant open,strike any key!); getch(); exit(1); ,顺序建立文本文件,先输入原始数据暂存到数组boya中for(i=0;iname, 注意pp已经指向数组的末尾,再把boya中的数据保存到文本文件中 pp=boya; for(i=0;iname,pp-num, pp-age,pp-addr);,顺序读文本文件,首先
14、把文本文件中的数据读到数组boyb中 rewind(fp); /把文件内部位置指针扳回到开始处 for(i=0;iname,再把读到数组中的数据显示到屏幕上 qq=boyb; for(i=0;iname,qq-num, qq-age, qq-addr); 最后关闭文件 fclose(fp);,代码sqFscanfandFprintf.c,思考题,在线评测的输入输出数据用文件,而不是键盘和屏幕。,按数据块读写二进制文件函数,每次读若干块数据 size_t fread(void *ptr, size_t size, size_t count, FILE *fp) ptr :存放输人数据的首地址 s
15、ize:是每块的大小 count:是块数 size_t 是unsigned int的别名,每次写若干块数据 size_t fwrite (const void *ptr, size_t size, size_t count, FILE *fp); ptr :存放输出数据的首地址 size:是每块的大小 count:是块数,例5 按块读写学生信息,if( (fp=fopen(stuInfo.dat,wb+) = NULL) printf(“Cant open strike any key!); getch(); exit(1); ,输入原始数据到数组boya,printf(ninput data
16、n); for(i=0;iname,fwrite(pp,sizeof(struct stu),2,fp); 把pp指向的2个学生结构数据写入fp指向的文件中 rewind(fp); fread(qq,sizeof(struct stu),2,fp); 从fp指向的文件中读出2块学生结构数据保存到qq指向的数组,显示数据到屏幕上 printf(nnnametnumber age addrn); for(i=0;iname,qq-num, qq-age, qq-addr); 关闭文件,代码 freadfwriteStuRec.c,随机读写文件,随机文件是相对于某个文件记录范围而言,不是顺序的从头到尾读写,而是随机的确定一个位置(可以由用户任意指定一个位置),然后把记录写在对应的位置上或从该位置读出数据。,文件的定位,void rewind( FILE *fp ); /将文件内部位置指针置于开头; 注意:不是文件指针而