Chap12文件12.1学生成绩文件统计12.2用户信息加密和校验12.3文件综合应用:资金账户管理本章要点什么是文件?C文件是如何存储的?什么是文件缓冲系统?工作原理如何?什么是文本文件和二进制文件?怎样打开、关闭文件?怎样编写文件读写程序?怎样编写程序,实现简单的数据处理?12.1学生成绩文件统计【例12-1】有5位学生的计算机等级考试成绩被事先保存在数据文件C:\f12-1.txt(C盘根目录下的文件f12-1.txt,需事先准备好该文件)中,包括学号、姓名和分数,文件内容如下:301101Zhangwen91301102Chenhui85301103Wangweidong76301104Zhengwei69301105Guowentao55请读出文件的所有内容显示到屏幕,并输出平均分。#includestdio.h#includestdlib.h#includeprocess.hintmain(void){FILE*fp;/*1.定义文件指针*/longnum;charstname[20];inti,score;intavg_score=0;if((fp=fopen(c:\\f12-1.txt,r))==NULL)/*2.打开文件*/{printf(Fileopenerror!\n);exit(0);}续下页….例12-1源程序例12-1源程序/*3.文件处理(逐个读入和处理数据)*/for(i=0;i5;i++){/*从文件读入成绩保存到变量*/fscanf(fp,%ld%s%d,&num,stname,&score);avg_score+=score;/*统计总分*//*输出成绩到屏幕*/printf(%ld%s%d\n,num,stname,score);}/*输出平均分到屏幕*/printf(Averagescore:%d\n,avg_score/5);if(fclose(fp)){/*4.关闭文件*/printf(Cannotclosethefile!\n);exit(0);}return0;}接上页……12.1.2文件的概念文件:操作系统中的文件是指驻留在外部介质(如磁盘等)中的一个有序数据集。各种类型的文件程序文件:源文件、目标程序、可执行程序数据文件(输入/输出):文本文件、图像文件、声音文件、可执行文件等文件的特点:数据永久保存;数据长度不定;数据按顺序存取12.1.3文本文件和二进制文件C语言中的文件是数据流(由一个个的字节数据组成)文件的两种数据形式:ASCII码(文本文件textstream)字符流二进制码(二进制文件binarystream)二进制流二进制文件是直接把内存数据以二进制形式保存。例如,整数1234文本文件保存:49505152(4个字符)二进制文件保存:04D2(1234的二进制数)字节........字节字节字节字节字节12.1.4缓冲文件系统内存单元内存单元数据……缓冲器512字节……文件由操作系统自动完成程序控制由于磁盘速度慢直接把数据写到磁盘效率很低12.1.4缓冲文件系统向磁盘输出数据:数据缓冲区,装满缓冲区后磁盘文件。从磁盘读入数据:先一次性从磁盘文件将一批数据输入到缓冲区,然后再从缓冲区逐个读入数据到变量。数据……缓冲器512字节……文件由操作系统自动完成程序控制文件名内存单元内存单元用什么标识缓冲文件与文件类型指针用文件指针指示文件缓冲区中具体读写的位置FILE*fp;数据……缓冲器512字节……文件由操作系统自动完成程序控制fp同时使用多个文件时,每个文件都有缓冲区,用不同的文件指针分别指示。1.文件结构与自定义类型typedefFILE:结构类型,用typedef定义(见stdio.h)typedefstruct{shortlevel;/*缓冲区使用量*/unsignedflags;/*文件状态标志*/charfd;/*文件描述符*/shortbsize;/*缓冲区大小*/unsignedchar*buffer;/*文件缓冲区的首地址*/unsignedchar*curp;/*指向文件缓冲区的工作指针*/unsignedcharhold;/*其他信息*/unsignedistemp;shorttoken;}FILE;12.1.5文件结构与文件类型指针自定义类型(typedef):将C语言中的已有类型(包括已定义过的自定义类型)重新命名新的名称可以代替已有数据类型常用于简化对复杂数据类型定义的描述typedef已有类型名新类型名;typedefintINTEGER;inti,j;====INTEGERi,j;typedefint*POINT;int*p1;====POINTp1;自定义类型(typedef)的使用方法定义变量inti变量名新类型名intINTEGER加上typedeftypedefintINTEGER用新类型名定义变量INTEGERi;intnum[10]intNUM[10]typedefintNUM[10]NUMa===inta[10]2.文件类型指针FILE*fp指向文件缓冲区,通过移动指针实现对文件的操作数据……缓冲器512字节……文件由操作系统自动完成程序控制fp同时使用多个文件时,每个文件都有缓冲区,用不同的文件指针分别指示。如何使fp与具体文件挂钩?12.1.6文件控制块FCB文件控制块FCB(FileControlBlock)OS中对文件的操作控制通过FCB,处理的是FCB列表一个文件对应一个FCB文件缓冲区由程序中fopen语句动态创建打开文件时,FCB的内容信息被复制到文件缓冲区保存用文件指针指向文件缓冲区实现对文件数据的访问5用于”f1.txt”的FCB...0123456...打开文件表12程序访问到这里fp=fopen(“f1.txt”,”w”);fopen返回一个指向FILE结构的指针(在stdio.h中定义)“f1.txt”的FILE结构包括一个描述符,也就是作为进入打开文件表索引的小整数fp3当程序使用如下I/O调用:fprintf(fp,%s,”HelloWorld!”);程序把描述符放在FILE结构中,并使用描述符查找打开文件表中的FCB操作系统访问4程序调用操作系统服务,使用FCB中的数据控制磁盘上实际文件的所有输入和输出。注意:用户不能直接访问FCB当打开文件时,在磁盘上复制这一项12.1.7文件处理步骤四个步骤:①定义文件指针②打开文件:文件指针指向磁盘文件缓冲区③文件处理:文件读写操作④关闭文件12.2用户信息加密和校验【例12-2】为了保障系统安全,通常采取用户帐号和密码登录系统。系统用户信息存放在一个文件中,系统帐号名和密码由若干字母与数字字符构成,因安全需要文件中的密码不能是明文,必须要经过加密处理。请编程实现:输入5个用户信息(包含帐号名和密码)并写入文件f12-2.dat。要求文件中每个用户信息占一行,帐号名和加密过的密码之间用一个空格分隔。密码加密算法:对每个字符ASCII码的低四位求反,高四位保持不变(即将其与15进行异或)。12.2.1程序解析intmain(void){FILE*fp;/*1.定义文件指针*/inti;voidencrypt(char*pwd);structsysusersu;/*2.打开文件,进行写入操作*/if((fp=fopen(f12-2.txt,w))==NULL){printf(Fileopenerror!\n);exit(0);}for(i=1;i=5;i++){/*3.将5位用户帐号信息写入文件*/printf(Enter%ithsysuser(namepassword):,i);scanf(%s%s,su.username,su.password);/*输入用户名和密码*/encrypt(su.password);/*进行加密处理*/fprintf(fp,%s%s\n,su.username,su.password);/*写入文件*/}if(fclose(fp)){/*4.关闭文件*/printf(Cannotclosethefile!\n);exit(0);}return0;}/*加密算法*/voidencrypt(char*pwd){inti;/*与15(二进制码是00001111)异或,实现低四位取反,高四位保持不变*/for(i=0;istrlen(pwd);i++)pwd[i]=pwd[i]^15;}#includestdio.h#includestring.hstructsysuser{/*用户帐号信息结构*/charusername[20];charpassword[8];};12.2.2打开文件和关闭文件if((fp=fopen(f12-2.txt,w))==NULL){printf(Fileopenerror!\n);exit(0);}fopen(文件名,文件打开方式)使文件指针与相应文件实体对应起来程序对文件指针进行操作,即fp代表磁盘文件函数fopen()的返回值执行成功,则返回包含文件缓冲区等信息的FILE型地址,赋给文件指针fp不成功,则返回一个NULL(空值)exit(0):关闭所有打开的文件,并终止程序的执行参数0表示程序正常结束;非0参数通常表示不正常的程序结束文件打开方式fp=fopen(f12-2.txt,w)文件打开方式参数表文本文件(ASCII)二进制文件(Binary)使用方式含义使用方式含义“r”打开只读文件“rb”打开只读文件“w”建立只写新文件“wb”建立只写新文件“a”打开添加写文件“ab”打开添加写文件“r+”打开读/写文件“rb+”打开读/写文件“w+”建立读/写新文件“wb+”建立读/写新文件“a+”打开读/写文件“ab+”打开读/写文件文件读写与打开方式if读文件指定的文件必须存在,否则出错;if写文件(指定的文件可以存在,也可以不存在)if以w方式写if该文件已经存在原文件将被删去重新建立;else按指定的名字新建一个文件;elseif以a方式写if该文件已经存在写入的数据将被添加到指定文件原有数据的后面,不会删去原来的内容;else按指定的名字新建一个文件(与“w”相同);if文件同时读和写使用r+、w+或a+打开文件关闭文件if(fclose(fp)){printf(Cannotclosethefile!\n);exit(0);}fclose(文件指针)把缓冲区中的数据写入磁盘扇区,确保写文件的正常完成释放文件缓冲区单元和FILE结构体,使文件指针与具体文件脱钩。函数fclose()的返回值返回0:正常关闭文件返回非0:无法正常关闭文件12.2.3文件读写【例12-3】复制用户文件。将例12-2的用户信息文件f12-2.txt文件备份一份,取名为文件f12-3.txt。说明:运行程序前请将文件f12-2.txt与源程序放在同一目录下。例12-3源程序#includestdio.hintmain(void){FILE*fp1,*fp2;charch;if((fp1=fopen(f12-2.txt,r))==NULL){printf(Fileopenerror!\n);exit(0);}if((fp2=fopen(f12-3.txt,w))==NULL){printf(Fileopenerror!\n);exit(0);}while(!feof(fp1)){ch=fgetc(fp1);if(ch!=EOF)fputc(ch,fp2);}/*关闭文件f12-2.txt*/if(fclose(fp1)){printf(Cannotclosethefile!\n);exit(0);}/*关闭文件f12-3.txt*/if(fclose(fp2)){printf(Cannotclosethefile!\n);exit(0);}retur