310 likes | 599 Views
课件制作:刘达明 023-66834110. 《C 语言程序设计 》 龙昭华主编. 第 8 章 文 件. 第一节 文件的基本概念 第二节 文件操作的相关函数. 1 / 31. ………. n-2. n-1. 1. 2. 3. 4. 0. 结束标志. 课件制作:刘达明 023-66834110. (第八章 文 件). 第一节 文件的基本概念. 一、 C 文件的概念. 所谓 的 “ 文件 ” ( file )一般指: 存储在外部介质上的相关数据的集合 。存放
E N D
课件制作:刘达明 023-66834110 《C语言程序设计》龙昭华主编 第8章文 件 第一节 文件的基本概念 第二节 文件操作的相关函数 1 / 31
……… n-2 n-1 1 2 3 4 0 结束标志 课件制作:刘达明 023-66834110 (第八章 文 件) 第一节文件的基本概念 一、C文件的概念 所谓的“文件”(file)一般指:存储在外部介质上的相关数据的集合。存放 文件的外部介质有磁带、磁盘、光盘等外部存储器。数据包括:数字、文字、 图形、图象、声音、视频等。在本章所讲的文件是由数字和文字组成的数据文 件。 以前各章中所用到的输入输出,都是以屏幕等(标准输出文件指针:stdout) 为输出设备,以键盘(标准输入文件指针:stdin)为输入设备。而程序运行有时 需要把数据存放到磁盘中,这就要用到磁盘文件。 C语言把文件看作是一个字符(字节)的序列,即由一个一个的字符或字节的 数据顺序组成。换句话说,C语言是把每一个文件都看作是一个有序的字节流。 流是文件和程序之间的通道。一个C程序可以创建文件和对文件内容进行更 新、修改,在程序中所需的数据也可以从另一个文件中获得。 对文件的操作一般通过三个步骤完成:打开文件、读或写文件、关闭文件。 2 / 31
内 存 输入 输入(读) 输入缓冲区 外存 程序数据区 文件 输出缓冲区 输出 输出(写) 课件制作:刘达明 023-66834110 第一节文件的基本概念 (第八章 文 件) 二、文件系统 在C语言中,根据操作系统对文件的处理方式的不同,把文件系统分为缓冲 文件系统和非缓冲文件系统。ANSI C标准采用缓冲文件系统。 缓冲文件系统(又称标准I/O)是指操作系统在内存中为每一个正在使用的文 件开辟一个读写缓冲区。从内存向磁盘输出数据时,必须先送到内存缓冲区, 装满缓冲区后才一起送到磁盘去。如果从向内存读入数据,则一次从磁盘文件 将一批数据输入到内存缓冲区,然后再从内存缓冲区逐个地将数据送到程序数 据区(变量)。 3 / 31
课件制作:刘达明 023-66834110 第一节文件的基本概念 (第八章 文 件) 三、文件分类 缓冲文件系统解决了高速CPU与低速外存之间的矛盾,使用它延长了外存的 使用寿命,也提高了系统的整体效率。 非缓冲文件系统(又称系统I/O)是指系统不自动开辟确定大小的内存缓冲区, 而由程序自己为每个文件设定缓冲区。 标准I/O与系统I/O分别采用不同的输入输出函数对文件进行操作。由于ANSI C只采用缓冲文件系统,因此本章所讲的函数也只是处理标准I/O的函数。 1、从用户角度分类 从用户的角度文件分为标准设备文件和普通磁盘文件。 ⑴标准设备文件:是指与主机相连的各种外部设备,如显示器、打印机、键 盘等。在操作系统中,把外部设备也看作是一个文件来进行管理,把它们的输 入、输出等同于对磁盘文件的读和写。 标准输入文件指针:stdin。如果指定从stdin输入数据,就是键盘输入。 标准输出文件指针:stdout。如果指定stdout输出数据,就是屏幕等输出。 标准错误输出文件指针:stderr。标准错误输出也是从屏幕终端输出。 ⑵普通磁盘文件:本章所讲的文件主要针对磁盘文件。 4 / 31
ASCII文件形式 00110010 00110011 00110100 00110101 00110001 转换 内存存储形式 3(51) 4(52) 5(53) 2(50) 1(49) 00111001 00110000 整数:12345 直接 00111001 00110000 二进制文件形式 课件制作:刘达明 023-66834110 第一节文件的基本概念 (第八章 文 件) 2、按文件的编码方式分类 从文件的编码方式看,C文件分为ASCII文件和二进制文件。 ⑴ASCII文件(也称文本文件):ASCII文件在磁盘中存放时,每个字符对应一 个字节,用于存放对应的ASCII码。如:整型十进制数12345,按ASCII文件存放 则需要占用5个字节。可在屏幕上显示,但占用空间较大,读写操作要转换。 ⑵二进制文件:是对不同的数据类型,按其实际占用内存字节数存放。即内 存的存储形式,原样输出到磁盘上存放。如:整型十进制数12345,按二进制文 件存放只需要2个字节。屏幕显示为乱码,但占用空间小,读写操作效率高。 5 / 31
课件制作:刘达明 023-66834110 第一节文件的基本概念 (第八章 文 件) 四、文件指针 要调用磁盘上的一个文件时,必须知道与该文件有关的信息。比如文件名、 文件的当前读写位置、文件缓冲区大小与位置、文件的操作方式等。这些信息 被C语言系统保存在一个称作FILE的结构体中,它在stdio.h头文件中定义内。 FILE结构体的内容为(在使用文件操作时,一般不用关心FILE内部成员信息): typedef struct { int level; /*缓冲区“满”或“空”的程度*/ unsigned flags; /*文件状态标志*/ char fd; /*文件描述符*/ unsigned char hold; /*如无缓冲区不读取字符*/ int bsize; /*缓冲区大小*/ unsigned char *buffer; /*数据缓冲区位置*/ unsigned char *curp; /*文件定位指针*/ unsigned istemp; /*临时文件指示器*/ short token; /*用于有效性检查*/ }FILE; 6 / 31
课件制作:刘达明 023-66834110 第一节文件的基本概念 (第八章 文 件) 文件指针(续): 有了结构体FILE类型后,可以用它来定义若干个FILE类型的变量,以便存放 若干个文件的信息。如:FILE f[5]; 定义了一个结构体数组f,它有5个元素 可以用来存放5个文件的信息。 对于每一个要操作的文件,都必须定义一个指针变量,并使它指向该文件结 构体变量,这个指针称为文件指针。通过文件指针找到被操作文件的描述信息, 就可对它所指的文件进行各种操作。定义文件指针的一般形式为: FILE * 指针变量标识符; 如:FILE *fp;表示fp是一个指向FILE类型结构体的指针变量。可以使fp指 向某一个文件的结构体变量,从而通过该结构体变量中的文件信息能够访问该 文件。 如果有n个文件,一般应定义n个FILE类型的指针变量,使它们分别指向n个 文件所对应的结构体变量。 如:FILE *fp1 , *fp2 , *fp2 , *fp4; 可以处理4个文件。 注意:FILE是用typedef声明的文件信息结构体的别名,由C系统定义,用 户只能使用,不能修改,并且FILE必须大写。 7 / 31
课件制作:刘达明 023-66834110 (第八章 文 件) 第二节文件操作的相关函数 对文件的操作一般步骤包括:打开文件、读或写文件、关闭文件。在C语言 中,文件操作都是由库函数来完成的。这些库函数包含在stdio.h头文件中。 一、文件的打开与关闭 所谓打开文件,实际上是建立文件的各种有关信息,并使文件指针指向该文 件,以便进行其它各种操作。关闭文件则是断开指针与文件之间的联系,也就 禁止再对该文件进行操作。 1、文件的打开(fopen函数) ANSIC规定了标准输入输出函数库,用fopen()函数来实现打开文件。fopen 函数的原型为: FILE *fopen(char *filename,char *mode) 其中参数filename表示一个文件名,是用双引号括起来的字符串,这个字符串 可以是一个合法的带有路径的文件名。参数mode表示对文件的操作模式,mode 的值仍需要用双引号括起来,mode的取值及其含义详见教材P228的表8.1。 如:FIEL *fp1; fp1=fopen(“test.c”,”r”); 表示是在当前目录下打开文件 test.c,只允许进行“读”操作,并使fp指向该文件。 再如:FIEL *fp2; fp2=fopen(“c:\\tt\\test.exe”,”rb”); 表示打开C盘下 tt目录中的test.exe文件,是二进制文件,只允许按二进制方式进行读操作。 8 / 31
r 只读 打开一个已经存在的文本文件 ASCII 文件 操作 建立并打开一个文本文件 w 只写 a 打开或建立一个文本文件,在末尾写入 追加 rb 只读 打开一个已经存在的二进制文件 二进制 文件 操作 只写 建立并打开一个二进制文件 wb ab 追加 打开或建立一个二进制文件,在末尾写入 打开一个已经存在的文本文件 r+ 读写 ASCII 文件 操作 建立并打开一个文本文件 w+ 读写 a+ 打开或建立一个文本文件,在末尾写入 读写 rb+ 打开一个已经存在的二进制文件 读写 二进制 文件 操作 建立并打开一个二进制文件 wb+ 读写 读写 ab+ 打开或建立一个二进制文件,在末尾写入 课件制作:刘达明 023-66834110 第二节文件操作的相关函数 (第八章 文 件) 文件使用方式及其意义 9 / 31
课件制作:刘达明 023-66834110 第二节文件操作的相关函数 (第八章 文 件) 2、文件的关闭(fclose函数) fcolse函数的原型为: int fclose(FILE *fp) 功能:使文件指针变量与文件“脱钩”,释放文件结构体和文件指针。 返回值:关闭成功时返回0。否则(如磁盘空间不足、写保护或关闭已经关闭的文件)返回EOF,即-1。 特别注意,文件使用完后,一定要关闭文件,否则可能丢失数据。因为在关闭之前,首先将缓冲区的数据输出到磁盘文件中,然后再释放文件指针变量。 程序中的exit函数原型为: void exit(int status) 功能:终止程序。它将status的值发送给DOS环境变量。它在stdlib.h中声明。 #include <stdio.h> main() { FILE * fp; fp=fopen(“test.txt”,”w”); if (fp==NULL) { printf(“file open error! \n”); exit(0); /*终止程序*/ }else { printf(“file open OK! \n); fclose(fp); } } 10 / 31
课件制作:刘达明 023-66834110 第二节文件操作的相关函数 (第八章 文 件) 二、文件操作错误检测 1、feof函数 函数原型: int feof(FILE *fp) 功能:检查文件是否结束。 返回值:若遇文件结束符,则返回非0值。否则返回0值。 2、ferror函数 函数原型: int ferror(FILE *fp) 功能:判断文件流上是否有错误。 返回值:若正确,则返回0。若发生错误,则返回非零值。 注意:对同一个文件在每一次调用输入输出函数(如:putc、getc、fread、 fwrite等)时,均产生一个新的ferror函数值。因此,应当在调用一个输入输出 函数后立即检查ferror函数的值,否则信息会丢失。在执行fopen函数时, ferror函数的初始值自动置为0。 3、clearerr函数 函数原型: void clearerr(FILE *fp) 功能:使文件错误标志(ferror的值)和文件结束标志(feof的值)置为0。 11 / 31
课件制作:刘达明 023-66834110 第二节文件操作的相关函数 (第八章 文 件) 三、顺序文件的读写 文件的顺序读写,是指文件被打开后,按照数据流的先后顺序对文件进行读 写操作。每读写一次后,文件指针自动指向下一个读写位置。 1、单个字符的读写函数(fgetc和fputc) ⑴fgetc函数(与getc一样) 函数原型: int fgetc(FILE *fp) 功能:从fp所指向的文件中取得下一个字符。 返回值:若正常,则返回所得到的字符ASCII码值。否则读到文件尾(键盘输 入时Ctrl+Z表示文件结尾)或出错,返回-1(EOF)。 注意:前面讲过的getchar函数实际上是以下宏定义来实现的: #define getchar() fgetc(stdin) 说明:①在fgetc函数调用中,读取的文件必须是以读或读写方式打开的。 ②读取字符的结果也可以不向字符变量赋值,这时读出的字符被丢失。③在文 件内部有一个位置指针,用来指向文件的当前读写字节。该指针由系统自动设 置,用户不用关心。每执行一次fgetc该指针自动下移一个字节,因此fgetc可 用在循环中读取文件的所有字符。 12 / 31
课件制作:刘达明 023-66834110 第二节文件操作的相关函数 (第八章 文 件) ⑵fputc函数(与putc一样) 函数原型: int fputc(int ch, FILE *fp) 功能:把一个字节代码ch写入fp所指向的文件中。 返回值:若正常,则返回字符ch的ASCII码值。否则出错,返回-1(EOF)。 注意:前面讲过的putchar函数实际上是以下宏定义来实现的: #define putchar(ch) fputc((ch),stdout) 说明: ①被写入的文件可以用写、读写、追加方式打开。 ②用写或读写方式打开一个已存在的文件时将清除原有的文件内容,写入字 符从文件首开始。 ③如需要保留原有文件内容,希望写入的字符从文件末尾开始存放,必须以 追加方式打开文件。 ④被写入的文件若不存在,则自动创建该文件。 ⑤每写入一个字符,文件内部位置指针向后移动一个字节。 13 / 31
课件制作:刘达明 023-66834110 第二节文件操作的相关函数 (第八章 文 件) 例8.1 从键盘输入字符存入文件中,以#号结束。 #include <stdio.h> main() { FILE *fp; char ch,filename[10]; scanf(“%s”,filename); if ((fp=fopen(filename,”w”))==NULL) { printf(“cannot open file!\n”); exit(0); } ch=getchar(); /*读scanf的回车符*/ ch=getchar(); /*输入第一个字符*/ while(ch!=‘#’) { fputc(ch,fp); putchar(ch); ch=getchar(); } fclose(fp); } 如果需要从文件读入字符 然后显示,需在最后增加 以下语句: fp=fopen(filename,”r”); if (fp==NULL) exit(0); while(!feof(fp)) { ch=fgetc(fp); putchar(ch); } fclose(fp); 运行情况如下: file.txt (回车) Comput and c# (回车) Comput and c 注:也可用fflush(stdin) 清除scanf留下的回车符。 再看例:教材P230例8.1。 14 / 31
课件制作:刘达明 023-66834110 第二节文件操作的相关函数 (第八章 文 件) 2、字符串的读写函数(fgets和fputs) ⑴fgets函数 函数原型: char * fgets(char *string, int n, FILE *fp) 功能:从fp所指向的文件中读n-1个字符,放到以string为起始地址的存储 空间(string可以是数组名)。若在n-1个字符前,遇到回车换行符或文件结束 符,则读操作结束。在读入的最多n-1个字符后面加一个字符串结束符‘\0’标 志,使读出的存放在string中字符数组为字符串。 返回值:若操作成功,则返回string的首地址。否则出错,返回NULL。 ⑵fputs函数 函数原型: int fputs(char *string, FILE *fp) 功能:将string所表示的字符串内容(不含最后的‘\0’)输出到fp所指向的文 件中去。 返回值:若操作成功,则返回一个非负数。否则出错,返回-1(EOF)。 15 / 31
课件制作:刘达明 023-66834110 第二节文件操作的相关函数 (第八章 文 件) 例8.2 从文件中按行读取字符串。 #include <stdio.h> main(int argc,char *argv[]) { FILE *fp; char w[81]; int lines=0; if (argc!=2) exit(1); if ((fp=fopen(argv[1],”r”))==NULL) { printf(“cannot open file!\n”); exit(0); } while(fgets(w,80,fp)!=NULL) { lines++; puts(w); } printf(“lines=%d\n”,lines); fclose(fp); } 注: 这个例子实现的是DOS命 令中的type命令的内容。 功能为:显示文本文件。 格式: type 文件名 再看: 教材P232的例8.3。 和: 教材P233的例8.4。 16 / 31
课件制作:刘达明 023-66834110 第二节文件操作的相关函数 (第八章 文 件) 3、数据块读写函数(fread和fwrite) C语言还提供了用于整块数据的读写函数。可用来读写一组数据,如一个数 组元素,一个结构体变量的值等。 ⑴fread函数 函数原型: int fread(void *buf, int size, int count, FILE *fp) 其中:buf:是一个指针,表示存放读入数据的首地址。 size:表示要读入的数据块的字节数。 count:表示要读入的数据块的块数,即有count个size字节的数据块 fp:表示文件指针。 功能:从fp所指向的文件中读取count个size字节的数据项,放到由buf所指 的内存地址中。 返回值:若读取成功,则返回count的值,即读取数据项的完整个数。否则 出错,返回-1(EOF)。 注:①读取成功时,实际读取的数据块可能小于代入的count的值。 ②fread函数通常用于二进制文件的操作。 17 / 31
课件制作:刘达明 023-66834110 第二节文件操作的相关函数 (第八章 文 件) ⑵fwrite函数 函数原型: int fwrite(void *buf, int size, int count, FILE *fp) 其中:buf:是一个指针,表示存放写入数据的首地址。 size:表示要写入的数据块的字节数。 count:表示要写入的数据块的块数,即有count个size字节的数据块 fp:表示文件指针。 功能:将buf所指的内存地址中的count个size字节的数据项写入fp所指向的 文件中。 返回值:若写入成功,则返回count的值,即写入数据项的完整个数。否则 出错,返回-1(EOF)。 注:①写入成功时,实际写入的数据块可能小于代入的count的值。 ②fwrite函数通常用于二进制文件的操作。 ③如果文件以二进制形式打开,用fread和fwrite函数就可以读写任何 类型的信息。 18 / 31
课件制作:刘达明 023-66834110 第二节文件操作的相关函数 (第八章 文 件) 例8.3 从磁盘文件stu_dat中读数据存入stu_list文件中。 #include <stdio.h> #define SIZE 4 struct student_type { char name[10]; int num; int age; char addr[15]; }stud[SIZE]; void save(); void load(); main() { load(); save(); } void save() { FILE *fp; int i,len; len=sizeof(stuct student_type); if((fp=fopen(“stu_list”,”wb”))==NULL) { printf(“cannot open file!\n”); return; } for(i=0;i<SIZE;i++) if(fwrite(&stud[i],len,1,fp)!=1) printf(“file write error!\n”); fclose(fp); } 19 / 31
课件制作:刘达明 023-66834110 第二节文件操作的相关函数 (第八章 文 件) 例8.3(续) void load() { FILE *fp; int i,len; len=sizeof(stuct student_type); if((fp=fopen(“stu_dat”,”rb”))==NULL) { printf(“cannot open infile!\n”); return; } for(i=0;i<SIZE;i++) if(fread(&stud[i],len,1,fp)!=1) { if(feof(fp)) { fclose(fp); return; } printf(“file read error!\n”); } fclose(fp); } 如果需要通过键盘输入数据,再存 入stu_dat文件,则main函数改为: main() { int i; for(i=0;i<SIZE;i++) scanf(“%s %d %d %s”, stud[i].name, &stud[i].num, &stud[i].age, stud[i].addr); save(); } 运行情况: Zhang 1001 19 room_101 (回车) Hu 1002 20 room_102 (回车) Tan 1003 21 room_103 (回车) Ling 1004 21 room_104 (回车) 20 / 31
课件制作:刘达明 023-66834110 《C语言程序设计》龙昭华主编 第8章文 件----习题1 习 题 (一) *** 复习本章已讲内容,预习本章剩余内容。 8.1 教材P243的习题8.2二级考试模拟题中的第⑵小题多选题。 8.2 教材P247的习题8.2二级考试模拟题中的第⑹小题编写程序中 的第①、②小题。 21 / 31
课件制作:刘达明 023-66834110 第二节文件操作的相关函数 (第八章 文 件) 4、格式化读写函数(fscanf和fprintf) ⑴fscanf函数 函数原型: int fscanf(FILE *fp, char *format, &arg1, …, &argn) 功能:按照format给出的控制符格式,把从fp所指向的文件中读取的内容, 分别赋给变元arg1,…,argn。 返回值:若读取成功,则返回已读取数据的个数。若遇文件结束,则返回-1 (EOF)。若出错,返回0。 ⑵fprintf函数 函数原型: int fprintf(FILE *fp, char *format, arg1, …, argn) 功能:按照format给出的控制符格式,将变元arg1,…,argn的值写入到fp所 指向的文件中去。 返回值:若写入成功,则返回实际写入数据的个数。若出错,则返回负数。 说明:①格式化读写均采用ASCII码方式,简单直观,易于理解。②在输入输出 时要进行ASCII码与二进制之间的转换,花费时间,影响速度。③如果文件数据 输入输出频繁或文件过大以及对二进制文件不宜采用格式化读写,而应采用数 据块读写函数fread()和fwrite()。 22 / 31
课件制作:刘达明 023-66834110 第二节文件操作的相关函数 (第八章 文 件) 例8.4 从磁盘文件vehicle.dat中读车流量数据存入vehicle1.dat文件中。 #include <stdio.h> main() { FILE *fp1,*fp2; char w[10]; int road1,road2; fp1=fopen(“vehicle.dat”,”r”); fp2=fopen(“vehicle1.dat”,”w”); if(fp1==NULL||fp2==NULL) { printf(“open file error!\n”); exit(0); }else { while(!feof(fp1)) { fscanf(fp1,”%s %d %d”,w, &road1,&road2); fprintf(fp2,”%s %d %d”, w,road1,road2); } /*end while*/ } /*end if*/ } 例子还可参见: 教材P237的例8.7。 23 / 31
s[1] s[0] i 课件制作:刘达明 023-66834110 第二节文件操作的相关函数 (第八章 文 件) 5、读写一个字(整数)函数(putw和getw) 如:FILE *fp; putw(10,fp);的作用是将整数10输出到fp指向的文件。而 FILE *fp; int i; i=getw(fp); 的作用是从磁盘文件读一个整数到内存,赋给 整型变量i。ANSIC并不提供这两个函数,因此有的C系统不包括putw和getw函数 这时可用如下函数来实现: putw函数定义如下: int putw(int i,FILE *fp) { char *s; s=(char *)&i; fputc(s[0],fp); fputc(s[1],fp); return(i); } getw函数定义如下: int getw(FILE *fp) { char *s; int i; s=(char *)&i; /* 使s指向i的起始地址 */ s[0]=fgetc(fp); s[1]=fgetc(fp); return(i); } 24 / 31
课件制作:刘达明 023-66834110 第二节文件操作的相关函数 (第八章 文 件) 四、随机文件的读写 随机文件的读写,是指在对文件进行读写操作时,可以对文件中指定位置的 信息进行读写操作。这样就需要对文件进行详细定位。 一般地,随机文件的读写适合于具有固定长度记录的文件。 C语言提供了一组用于随机读写的定位函数,其函数原型都在stdio.h中。采 用随机读写文件可以在不破坏其它数据的情况下把数据插入到文件中去,也能 在不重写整个文件的情况下更新和删除以前存储的数据。 在结构体类型FILE中有一个文件定位指针(unsigned char *curp;),实现随 机读写的关键是要按要求移动该位置指针,这称为文件的定位。 1、文件定位函数(rewind、fseek和ftell) ⑴rewind函数 函数原型: void rewind(FILE *fp) 功能:将fp所指向的文件的内部位置指针置于文件开头,并清除文件结束标 志和错误标志。 返回值:该函数没有返回值。 如:rewind(fp); 表示强制将文件指针指向文件头。 25 / 31
课件制作:刘达明 023-66834110 第二节文件操作的相关函数 (第八章 文 件) ⑵fseek函数 函数原型: int fseek(FILE *fp,long offset,int base) 其中:base为“起始点”,分别用0、1、2代表,其含义与名字如下: 文件开始 SEEK_SET 0 文件当前位置 SEEK_CUR 1 文件末尾 SEEK_END 2 offset为位移量,是指以“起始点”为基点移动的字节数。当位移量为负 数时,表示向文件头方向移动(也称后移)。当位移量为正数时,表示向文件尾 方向移动(也称前移)。 功能:改变文件位置指针的位置。 返回值:成功时返回0;失败时返回-1(EOF)。 如:fseek(fp,20L,0); 表示将文件指针从文件头向前移动20个字节。 fseek(fp,-100L,1); 表示将文件指针从当前位置向后移动100个字节。 fseek(fp,-30L,SEEK_END); 表示将文件指针从文件尾向后移动30个字节。 说明:fseek()函数一般用于二进制文件。因为文本文件要进行字符转换,故往 往计算的位置会出现混乱或错误。 26 / 31
课件制作:刘达明 023-66834110 第二节文件操作的相关函数 (第八章 文 件) ⑶ftell函数 函数原型: long ftell(FILE *fp) 功能:得到fp所指向的文件中的当前位置。该位置用相对于文件头的位移量 来表示。 返回值:成功时返回当前读写的位置;失败时返回-1L(EOF)。 如:long i; FILE *fp; i=ftell(fp); 2、随机文件的读写函数说明 ①对文件进行定位之后,即在改变文件位置指针之后,即可用前面介绍的任 一种读写函数对文件进行随机读写。 ②由于一般是读写一个数据据块,因此常用fread()和fwrite()函数随机文 件的读写操作。 ③由于定位是否准确的原因,随机文件的操作一般又是对二进制文件进行操 作。 ④有的教材对随机文件的操作只介绍了这里的定位函数,还有块数据读写函 数。而对前面介绍的除块数据读写函数外的其它函数都认为是顺序文件函数。 27 / 31
课件制作:刘达明 023-66834110 第二节文件操作的相关函数 (第八章 文 件) 例8.5 建立一个可记录100个客户的银行帐户(帐号、姓名、金额)存文件。 #include <stdio.h> struct bankclient { int count; /* 取值为1—100*/ char name[10]; float money; }; main() { FILE *fp; int rlen,i,off; struct bankclient client={0,””,0.0}; rlen=sizeof(struct bankclient); fp=fopen(“credit.txt”,”w”); if(fp==NULL) { printf(“open file error!\n”); exit(0); } for(i=1;i<=100;i++) /*建立*/ fwrite(&client,rlen,1,fp); fclose(fp); fp=fopen(“credit.txt”,”r+”); if(fp==NULL) { printf(“open file error!\n”); exit(1); } /*以下为修改数据*/ scanf(“%d”,&client.count); getchar(); while(client.count!=0) { gets(client.name); scanf(“%f”,&client.money); getchar(); off=(client.count-1)*rlen; 28 / 31
课件制作:刘达明 023-66834110 第二节文件操作的相关函数 (第八章 文 件) 例8.5(续) 运行情况: 34 (enter) DaHai (enter) 450.6 (enter) 45 (enter) ShanDin (enter) 460.8 (enter) 67 (enter) BaiLu (enter) 890.2 (enter) 0 (enter) ------------------------------------- Account Name Balance 34 DaHai 450.6 45 ShanDin 460.8 67 BaiLu 890.2 fseek(fp,off,0) ; fwrite(&client,rlen,1,fp); scanf(“%d”,&client.count); getchar(); } /*end while*/ rewind(fp); /*以下为屏幕输出*/ printf(“---------------------------------------\n”); printf(“%5s%10s%10s\n”,”Account”, “Name”,”balance”); while(!feof(fp)) { fread(&client,rlen,1,fp); if(client.count!=0) printf(“%5d%10s%8.2f\n”,client.count, client.name,client.money); } fclose(fp); } 29 / 31
课件制作:刘达明 023-66834110 第二节文件操作的相关函数 (第八章 文 件) 例8.6 把一个浮点数组以二进制方式写入文件test_b.dat中。并读出来。 #include <stdio.h> main() { float f[6]={3.2, -4.34, 25.04, 0.1, 50.56, 80.5},t[6]; int i; FILE *fp; /*创建一个二进制文件只写*/ fp=fopen("test_b.dat", "wb"); /*将6个浮点数写入文件中*/ fwrite(f, sizeof(float), 6, fp); fclose(fp); fp=fopen("test_b.dat", “rb"); fread(t,sizeof(float),6,fp); for(i=0;i<6;i++) printf(“t[%d]=%5.2f\n”,i,t[i]); } 运行结果: t[0]= 3.20 t[1]=-4.34 t[2]=25.04 t[3]= 0.10 t[4]=50.56 t[5]=80.50 其它例子: 参见教材P240的例8.8。 30 / 31
课件制作:刘达明 023-66834110 《C语言程序设计》龙昭华主编 第8章文 件----习题2 习 题 (二) *** 复习本章已讲内容。 8.3 教材P241的习题8.1基本知识题中的第⑴ 至 ⑸小题。 8.4 教材P242-243的习题8.2二级考试模拟题中的第⑴小题单选题。 8.5 教材P243的习题8.2二级考试模拟题中的第⑶小题判断题。 8.6 教材P247的习题8.2二级考试模拟题中的第⑹小题编写程序中 的第③小题。 31 / 31