资源描述
,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,单击此处编辑母版标题样式,*,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,用语言编写程序,本章要点,什么是文件?C文件是如何存储的?,什么是文件缓冲系统?工作原理如何?,什么是文本文件和二进制文件?,怎样翻开、关闭文件?,怎样编写文件读写程序?,怎样编写程序,实现简单的数据处理?,12.1 学生成绩文件统计,12.1.1 程序解析,12.1.2 文件的概念,12.1.3 文本文件和二进制文件,12.1.4 缓冲文件系统,12.1.5 文件构造与文件类型指针,12.1.6 文件控制块,12.1.7 文件处理步骤,12.1.1 程序解析,【,例,12-1】,有,5,位学生的计算机等级考试成绩被事,先保存在数据文件,C:f12-1.txt,中,包括学号、姓,名和分数,文件内容如下:,301101 Zhangwen 91,301102 Chenhui 85,301103 Wangweidong 76,301104 Zhengwei 69,301105 Guowentao 55,请读出文件的所有内容显示到屏幕,并输出平均分。,例,12-1,程序,#include ,#include ,#include ,int main(void), FILE *fp; /* 定义文件指针*/,long num;,char stname20;,int i, score; int avg_score = 0; /* 翻开文件 */,if(fp=fopen(c:f12-1.txt,r)= NULL), printf( error!n);,exit(0);,for(i=0; i5; i+) /*,从文件读入成绩,*,/,fscanf,(fp,%ld%s%d, ,avg_score += score; /*,统计总分,*,/,printf(%ld %s %dn,num, stname, score);,/*,输出平均分,*,/,printf(Average score: %dn, avg_score/5);,if(,fclose,(fp) /*,关闭文件,*,/, printf( Can not close the file!n );,exit(0);,return 0;,例,12-1,程序,12.1.2 文件的概念,文件是,存储,在,外部介质,上的一个有序数据集合。,由操作系统来管理,。,最常用的是磁盘文件。,从文件数据的组织形式可分为文本文件和二进制文件,。,C,语言中的输入输出操作可涉及的并不只限于键,盘和显示器,还可以是文件,特别在输入输出数,据量较大时。,文件的大容量、可编辑、易交流和能保存等特点,是键盘和显示器不可相比的。,12.1.3,文本文件和二进制文件,C,语言把文件都看作数据流,文本文件为字符流,二进制文件为二进制流,对文件的读写是以字节为,单位的。,文本文件是把数据以一串字符的形式,每个字符,以其,ASCII,码值存储。,二进制文件是把数据按内存中的存储形式存储。,例如,整数,1234,文本文件存储:,49 50 51 52,(,4,个字符,ASCII,码,),二进制文件存储:,00 00 04 D2,(,1234,的二进制数,),12.1.4 缓冲文件系统,ANSI C规定,对文件进展输入或输出时,系统,将为输入或输出文件开辟缓冲区。,缓冲文件系统的工作原理如以下图所示。,操作系统自动完成,文件,512,字节,程序控制,内存缓冲区,程序数据区,12.1.5 文件构造与文件类型指针,1.,自定义类型,C,语言允许用,typedef,对已有类型名再定义一个,新类型名,,typedef,语句的一般形式为:,typedef,已有类型名,新类型名,;,其中:,已有类型名,:,包括,C,语言中规定的类型和已定义,过的自定义类型。,新类型名,:,为一标识符,一般习惯用大写。,新类型名,相当于是,已有类型名,的,别名,,该,已有类,型名,依然有效,。,12.1.5 文件构造与文件类型指针,如: typedef float REAL;,那么: REAL a, b; float a, b; 等价,如: typedef int NUM10;,那么: NUM n, m; int n10, m10; 等价,如: typedef char * STRING;,那么: STRING p,s10; char *p,*s10; 等价,如: typedef struct student, char num4; float score; NODE;,那么:NODE st,*p; struct student st,*p; 等价,12.1.5 文件构造与文件类型指针,2. 文件(构造)类型 FILE,构造类型 FILE 在 stdio.h 中用 typedef 定义:,typedef struct, short level; /* 缓冲区使用量 */,unsigned flags; /* 文件状态标志 */,char fd; /* 文件描述符 */,short bsize; /* 缓冲区大小 */,unsigned char *buffer; /* 文件缓冲区的首地址 */,unsigned char *curp; /* 指向文件缓冲区的工作指针 */,unsigned char hold; /* 其他信息 */,unsigned istemp;,short token;, FILE;,12.1.5 文件构造与文件类型指针,3. 文件类型指针,定义文件类型指针的一般形式:,FILE * 变量名;,例如,FILE *fp, *fpi, *fpo;,系统为输入或输出文件开辟缓冲区的同时,还为,该文件定义并初始化了一个文件类型的构造变量,,包含有诸如缓冲区首地址、当前存取位置、对文件,是读还是写等信息。,定义一个文件指针指向该文件类型的构造变量,,从而可通过其中各项信息来实现对该文件的操作。,12.1.5 文件构造与文件类型指针,一般编程者无需关心文件构造变量的具体内容,,程序中只使用指向其的文件指针,用文件指针代表,文件整体,对文件指针也不必和不能进展除赋值指,向外的任何操作。,文件控制块,FCB,文件控制块FCB Block,OS中对文件的操作控制通过FCB,处理的是FCB列表,一个文件对应一个FCB,文件缓冲区由程序中fopen语句动态创立,翻开文件时, FCB的内容信息被复制到文件缓冲区保存,用文件指针指向文件缓冲区实现对文件数据的访问,12.1.7 文件处理步骤,文件处理的四个步骤:, 定义文件指针, 翻开文件:文件指针指向磁盘文件缓冲区, 文件处理:文件读写操作, 关闭文件,12.2 用户信息加密和校验,12.2.1 程序解析,12.2.2 翻开文件和关闭文件,12.2.3 文件读写,12.2.4 其他相关函数,12.2.1 程序解析,【例12-2】为了保障系统平安,通常采取用户帐号,和密码登录系统。系统用户信息存放在一个文件中,系统帐号名和密码由假设干字母与数字字符构成,因,平安需要文件中的密码不能是明文,必须要经过加,密处理。请编程实现:输入5个用户信息(包含帐号,名和密码)并写入文件。要求文件中每个用,户信息占一行,帐号名和加密过的密码之间用一个,空格分隔。密码加密算法:对每个字符ASCII码的低,四位求反,高四位保持不变(即将其与15进展异或) 。,例,12-2,程序,#include ,#include ,struct sysuser /*用户帐号信息构造*/,char name20; /* 用户名*/,char pw8; /* 密码 */,;,/*加密算法:与0x0F异或,实现低四位取反,高四位不变*/,void encrypt(char *pwd), int i;,for(i = 0; i strlen(pwd); i+),pwdi = pwdi 15;,int main(void), int i; FILE *fp; /* 定义文件指针 */,struct sysuser su;,if(fp=fopen(f12-2.txt,w) = NULL) /*翻开文件*/, printf( error!n); exit(0); ,for(i=1;i=5;i+), printf(Enter %i th sysuser,(name password):,i);,scanf(%s%s, su.name, su.pw); /* 键盘输入*/,encrypt(su.pw); /* 加密处理 */,fprintf(fp,%s %sn,su.name,su.pw); /*写文件*/,if(fclose(fp) /* 关闭文件 */, printf(Can not close the file!n); exit(0); ,return 0;,例,12-2,程序,12.2.2 翻开文件和关闭文件,1. 翻开文件,文件翻开函数 fopen( ),原型: FILE *fopen(char *fname, char *mode);,功能: 以mode方式翻开文件fname。如成功,返回指,向翻开文件的文件指针;如失败,返回NULL。,其中:,*fname 字符串,要翻开文件的文件名及其路径。,*mode 字符串,文件使用方式或称翻开方式。,例如,; char *p=d:f.txt;,fp = fopen( d:f.txt, r );,或 fp = fopen( p, r );,12.2.2 翻开文件和关闭文件,文件翻开方式,文本文件,二进制文件,方式,含义,方式,含义,r,打开文件只读,rb,打开文件只读,w,建立文件只写,wb,建立文件只写,a,打开文件追加,ab,打开文件追加,r+,打开文件读,/,写,rb+,打开文件读,/,写,w+,建立文件读,/,写,wb+,建立文件读,/,写,a+,打开文件读,/,写,/,追加,ab+,打开文件读,/,写,/,追加,文件读写与翻开方式,if (读文件),指定的文件必须存在,否那么出错;,if (写文件),if ( w ),if (该文件已存在) 原文件将被删去重新建立;,else 按指定的名字新建一个文件;,else if ( a ),if(文件已存在) 写入数据将追加到原有数据的后面;,else 按指定的名字新建一个文件(同w);,if (文件同时读和写),使用 r+、w+ 或 a+ 翻开文件;,12.2.2 翻开文件和关闭文件,为确保文件正常翻开后再进展读写,可作如下形,式的判断,if(fp = fopen(f.txt, r) = NULL), printf( error!n);,exit(0); /* 原型: void exit ( int status ); */, /* 功能: 关闭所有文件,终止程序运行 */,文件翻开后,所指定的翻开方式直到文件关闭都,不能改变。,允许同时翻开多个文件,不同文件要用不同文件,指针指示。不允许同一文件在关闭前再次翻开。,12.2.2 翻开文件和关闭文件,2. 关闭文件.,文件关闭函数 fclose( ),原型: int fclose(FILE *fp);,如果文件关闭成功,返回0,如检测到任何错误,,那么返回EOF(即-1,在中定义)。,对文件是否正常关闭,可作如下形式的判断。,if(fclose(fp), printf(Can not close the file!n);,exit(0);,12.2.3 文件读写,1. 字符方式文件读写函数fgetc和fputc,写一个字符的函数 fputc( ),原型:int fputc(char ch, FILE *fp);,功能:将字符 ch 写到fp指向的文件中去,成功,那么,返回该字符,否那么返回EOF。,读一个字符的函数 fgetc(),原型:int fgetc(FILE *fp);,功能:从一翻开的文件中读一个字符,返回该字符。,文件中有一个指向当前位置的指针自动后移一,个字符。反复调用可一直读到文件完毕。文件,完毕或出错时,返回EOF。,12.2.3 文件读写,【,例,12-3】,复制用户文件。将例,12-2,的用户信息文,件文件备份一份,取名为文件。,#include ,int main(void), FILE *fp1,*fp2;,char c;,if(,(,fp1 =,fopen,( f12-2.txt,r,),),= NULL), printf( error!n );,exit(0);,if( fp2 =,fopen,(f12-3.txt,w,) = NULL), printf( error!n);,exit(0);,while( !feof( fp1 ) ), c =,fgetc,( fp1 );,if(ch != EOF),fputc,(c, fp2);,if(,fclose,(fp1), printf(Can not close the file!n); exit(0); ,if(,fclose,(fp2), printf(Can not close the file!n); exit(0); ,return 0;,例,12-3,程序,12.2.3 文件读写,2. 字符串方式文件读写函数fgets和fputs,读字符串函数fgets(),原型:char *fgets(char *string, int n, FILE *fp);,功能:从fp指定的文件读取长度为n-1的字符串存,入起始地址为string的内存空间,自动加完毕标志,0,共占n个字符,返回值为地址string。,假设在未读足n-1个字符前遇到换行符n或文件完毕,就停顿读取。,假设读到文件末尾或出错,那么返回NULL值。,12.2.3 文件读写,写字符串函数fputs(),原型:int fputs(char *string, FILE *fp);,功能:将string指向的字符串写到 fp 指定的文件。,但不写入字符串完毕符0。,写成功,那么返回所写的最后一个字符,否那么返回,EOF值。,12.2.3 文件读写,【例12-4】例12-2的文件保存着系统用户,信息,编写一个函数checkUserValid()用于登录系,统时校验用户的合法性。检查方法是:,在程序运行时输入用户名和密码,然后在用户文件中查找该用户信息,如果用户名和密码在文件中找到,那么表示用户合法,返回1,否那么返回0。,程序运行时,输入一个用户名和密码,调用checkUserValid()函数,如果返回1,那么提示“Valid user!,否那么输出“Invalid user!。,#include ,#include ,struct sysuser /*用户帐号信息构造*/,char name20; /* 用户名*/,char pw8; /* 密码 */,;,void encrypt(char *pwd) /* 加密函数 */, int i;,for(i = 0; i username);,strcpy(pwd, psu-password);,encrypt(pwd); /*,密码加密,*,/,strcat(usr, );,/*,将用户名,和,加密后密码,*,/,strcat(usr, pwd);,/*,连接成文件中相应格式,*,/,strcat(usr, n);,/*,的字符串,*,/,if(fp=fopen(f12-2.txt,r,)=NULL), printf( error!n); exit(0); ,例,12-4,程序,例,12-4,程序,while(!feof(fp),fgets(usr1, 30, fp),; /*,读入一个用户信息,*,/,if(strcmp(usr, usr1)=0), check=1; break; ,if(,fclose,(fp), printf(Can not close the file!n); exit(0); ,return check;,12.2.3 文件读写,3.,格式化方式文件读写,fscanf,和,fprintf,调用格式:,fscanf ( FILE *fp,格式字符串,输入表,),fprintf ( FILE *fp,格式字符串,输出表,),说明,这两个函数与,scanf( ),和,printf( ),相似,只是读,写对象不同,前者是文件,后者是终端。,这两个函数读写的是文本文件。,12.2.3 文件读写,例如,FILE *fp; int n; float x;,fp = fopen(a.txt, r);,fscanf(fp, %d%f, ,表示从文本文件 a.txt 分别读入整型数到变量 n、,浮点数到变量 x。,fp = fopen(b.txt, w);,fprintf(fp, %d%f, n, x);,表示把变量 n 和 x 的数值写入文本文件 。,12.2.3 文件读写,4. 数据块方式文件读写函数fread和fwrite,原型: int fread (void *buf,int size,int n,FILE *fp);,int fwrite(void *buf, int size,int n,FILE *fp);,其中: void *buf:任何类型指向数据块(首址)的指针。,int size: 要读写的数据块字节数。,int n: 要读写的数据块个数。,FILE *fp: 指向已翻开的要读写文件的指针。,功能: 从fp指定的二进制文件读取或写入长度为size的n,个数据块,存到或取自 buf所指向的内存区。读或,写成功,返回读或写数据块个数n,失败返回0。,12.2.3 文件读写,【,例,12-5】,编程实现以二进制方式读写用户信息文,件,将,5,位用户信息写入文件,然后读出,所有用户信息并显示在屏幕上。,#include ,#include ,#define SIZE 5,struct sysuser,char name20;,char pw8;,;,void encrypt(char *pwd);,int main(void), FILE *fp; int i;,struct sysuser uSIZE,suSIZE,*pu=u,*psu=su;,if(fp = fopen(f12-5.dat,wb+,) = NULL), printf( error!n); exit(0); ,for(i=0; iname, pu-pw);,encrypt( /*,密码加密,*,/,pu=u;,fwrite(pu, sizeof(struct sysuser), SIZE, fp,);,例,12-5,程序,rewind(fp);,/*,位置指针重置于文件首,*,/,fread(psu, sizeof(struct sysuser), SIZE, fp);,for(i=0; iname, psu-pw);,if(fclose(fp), printf(Can not close the file!n); exit(0); ,return 0;,void encrypt(char *pwd),/*,加密函数,*,/, int i;,for(i = 0; i strlen(pwd); i+),pwdi = pwdi 15;,例,12-5,程序,12.2.4 其他相关函数,从定位文件首函数rewind(),void rewind( FILE *fp);,将 fp 指定的文件的当前位置指针重新置于文件的,开头位置。,文件末尾检测函数feof(),int feof(FILE *fp);,检测 fp 指定的文件的当前位置指针是否到达文件,完毕位置,如果是,返回非0值,否那么返回0。,12.2.4 其他相关函数,指针移动控制函数fseek(),int fseek(FILE *fp, long offset, int whence);,将 fp 指定的文件的当前位置指针移动到相对于由,whence 指定的位置偏移 offset 字节的新位置。,如移动成功,返回0,失败返回非0。,其中:,offset 以whence为基准位置,向前或向后移动,的字节数,值为正时,向文件尾移动,值为负时,,那么向文件头移动。,12.2.4 其他相关函数,whence 为移动位置指针的基准位置,可以是如,下数值或符号常量:,0 或 SEEK_SET 表示文件开场位置,1 或 SEET_CUR 表示文件当前位置,2 或 SEEK_END 表示文件末尾位置,例如:,fseek(fp, 20L, 0);,将位置指针移动到距文件首部20个字节处。,fseek(fp, -20L, SEEK_END):,将位置指针移动到距文件尾部前20个字节处。,12.2.4 其他相关函数,获取指针当前位置函数ftell(),long ftell( FILE *fp );,检测 fp 指定的文件的位置指针的当前位置,返回,相对于文件开头的位移量(字节数,文件第一个字,节的位移量为0)。如出错,那么返回-1L。,读写错误检查函数ferror(),int ferror( FILE *fp );,检测fp指定的文件在用各种输入输出函数进展读,写是否发生了错误,假设没有错误,返回0;假设发生,错误,返回非0。,12.2.4 其他相关函数,出错标记去除函数clearerr(),void clearerr(FILE *fp);,去除(置0)出错标志和文件完毕标志。,12.3,文件综合应用,:,资金账户管理,12.3.1,顺序文件和随机文件,按照C程序对文件访问的特点来分,文件可分为顺序,访问文件和随机访问文件,简称为顺序文件和随机文件。,前面介绍的所有例子都进展的是顺序访问,通过使用,fprintf 或 fputs 函数创立的数据记录长度并不是完全一,致的,这种记录长度不确定的文件访问称为顺序访问。,而随机访问文件要求文件中单个记录的长度固定,可直,接访问,这样速度快,并且无需通过其他记录查找特定,记录。因此随机文件适合银行系统、航空售票系统、销,售点系统和其他需要快速访问特定数据的事务处理系统。,12.3.2 个人资金账户管理,【例12-6】编程实现资金账户管理,要求如下:,资金账户的信息统一放在随机文件中,该随机文件,包括的数据项有记录ID、发生日期、发生事件、,发生金额正的表示收入,负表示支出和余额。,每发生一笔收支,文件要增加一条记录,并计算,一次余额。,程序实现3个功能,包括: 能创立资金账户文,件并添加收入或支出信息记录;, 能显示所有录, 得知资金账户的收支流水账;, 能查询最后一条记录,获知账户最后的余额。,12.3.2 个人资金账户管理,账户文件的局部内容如下:,LogID Create Date Note Charge Balance,本章总结,文件的概念,文本文件和二进制文件,文件缓冲系统,文件构造,文件指针,自定义类型,文件的翻开与关闭,文件处理实现过程,文件读写操作与常用文件操作函数,文件综合应用,本章完毕,谢谢大家!,结 语,
展开阅读全文