第十三章 文件
主要内容 文件的概念 文件的分类 文件的操作
一、文件的概念 所谓文件是具有符号名字的相关联的一组存储在外部介质上的信息集合。操作系统通过文件名和数据发生联系,从而实现对数据的管理。 返回
二、文件的分类 按数据存储形式分为:ASCII码文件和二进制文件。 按存储形式分类 ASCII码文件 二进制文件 存储形式 ASCII码 二进制形式 优点 一个字节不对应一个字符,便于对字符进行逐个处理,可直接输出字符形式。 可以节省外存空间和转换时间, 缺点 占用的存储空间较多,处理时需要花费较多的计算机时间进行转换。 一个字节不对应一个字符,不能直接输出字符形式。 例如:20 在ASCII码文件中,存储为:0011001000000000 在二进制文件中,存储为:00010100
二、文件的分类 返回 按文件的处理方式分类:缓冲文件和非缓冲文件。 1、缓冲文件:系统自动在内存区为每一个正在使用的 文件开辟一个512字节的缓冲区。从内存向磁盘文件 输出数据时,首先将数据送到内存缓冲区,待缓冲区 装满后再一起送到磁盘上。从磁盘向内存输入数据时, 首先从磁盘文件将一批数据输入到内存缓冲区,然后 再从缓冲区逐个地将数据送到程序数据区。 缓冲文件系统一般用于处理文本文件。 2、非缓冲文件:系统不自动开辟确定大小的缓冲区, 而由程序为每个文件设定缓冲区。 非缓冲文件系统一般用来处理二进制文件。 返回
三、文件的操作 C语言对文件的读写操作是用标准库函数实现的。 C语言规定了用于文件的标准输入、输出函数,利用他们可以完成对文件的读写操作。所有这些函数的原型都包含在头文件stdio.h中。 系统定义了一个FILE类型,用来说明文件的有关信息。 对文件的操作需要借助文件类型的指针来实现: 定义文件类型的指针变量,只需定义指针变量为文件类型即可: FILE *变量名; 例如:FILE *fp;
1、文件的打开 对文件进行操作,首先必须先打开文件。 打开文件使用函数 fopen(): 调用形式: FILE *fp; fp=fopen(文件名,文件的使用方式); 说明: 1、FILE用来定义指向文件的指针变量; 2、fopen将打开的文件的地址赋给文件指针,使其与打开的文件建立关系。以后可以通过fp来完成对文件的操作。 3、文件的使用方式是指对文件进行读、写或追加等操作。具体含义如课本P312表13.1所示。 4、如果文件打开失败则返回空指针:即fp==NULL;
1、编程,以只读的方式打开一个临时指定的文件,若打开成功,则输出success,否则输出error。见程序D13_1.c
2、文件的关闭 对文件操作完成之后,要及时关闭该文件,以释放空间,并防止误操作,丢失数据。 文件的关闭使用函数fclose() 调用形式: 关闭文件的作用: 1、将文件缓冲区中剩余的字节写进磁盘文件,以免数据丢失。 2、使系统释放该文件的FILE 结构以及所占用的文件缓冲区。 说明:若正常关闭,则该函数返回0;若关闭文件有错误,则该函数返回一个非0的数。
#include <stdio.h> main() {FILE *fp; char fname[20]; printf("\n input the file's name->"); scanf("%s",fname); fp=fopen(fname,"r+"); ……. …… fclose(fp);} 左面的代码是以读写的方式打开一个指定的文本文件,经过有关的操作后,关闭被打开的文件。
3、文件的读写 fgetc():从指定的文件中读一个字符。 使用格式:ch=fgetc(fp); 注意:使用该函数时,该文件必须是以读的方式打开的。 feof():用来判断文件是否结束。 使用格式:feof(fp); 参考filer.c 注意: 1、返回1时,文件结束,返回0时,文件没结束。 fputc():将指定字符写到指定的文件中去 使用格式:fputc(ch,fp); 参考filew.c 作用:将ch代表的字符写到fp指向的文件中。 若成功,则返回该字符,若不成功,则返回EOF。
例3:编程,从键盘输入字符,逐个送到指定的磁盘文件中,直到输入#为止。见程序D13_2.c 注意:系统自动建立了三个文件指针:stdin,stdout,stderr分别代表键盘、显示器、显示器。如果把程序中的p换成stdout,效果如何?
4:编程,把指定的文件内容显示在屏幕上。见程序D13_3.c 6、改写程序,使其运行形式类似于DOS的copy命令 见程序D13_5.c
3、文件的读写 fgets(): 使用格式:fgets(str,n,fp); 作用:从fp指向的文件中读一个字符串(最多n-1个字符),放入由str指向的字符数组中。 注意: 1、读取失败返回NULL。 2、若遇到字符串结束标志则结束(即使不够n-1个)。 fputs(): 使用格式:fputs(str, fp); 作用:将str指向的字符串写到fp指向的文件中。 注意: str可以是字符串常量、字符型指针或字符型数组名。
3、文件的读写 fread()和fwrite()一般用于二进制文件的读写。 fread(): 作用:从指定的文件中读入数据并赋给指定的变量。 例如:fread(fp,”%d,%f”,&I,&f); 注意: 读取失败返回负数,成功返回实际被赋值变量的个数。 fwrite(): 使用格式:fwrite(文件指针,格式字符串,变量列表); 作用:将指定的变量的内容写到指定的文件中。 例如:fwrite(fp,”%d,%6.2f”, I, f); 注意: 调用失败返回负数,成功返回实际写入数据的个数。 fread()和fwrite()一般用于二进制文件的读写。
7:编程,从键盘输入4个学生的有关情况(学号、姓名、年龄、地址)。然后把它们存到一个磁盘文件中。见程序D13_6.c 注意: fread函数和 fwrite函数都是按二进制形式读写文件的 7:编程,从键盘输入4个学生的有关情况(学号、姓名、年龄、地址)。然后把它们存到一个磁盘文件中。见程序D13_6.c 8:编程,把例1建立的文件内容读出,在屏幕显示。见程序D13_7.c 分析两个程序,总结fread和fwrite函数的使用特点。注意程序中的fread(stu,54,4,fp);可否换成如下代码 for (i=0;i<4;i++) fread(&stu[i],54,1,fp); 同样,for (i=0;i<4;i++) fwrite(&stu[i],54,1,fp);可否换成fwrite(stu,54,4,fp);
fprintf函数和 fscanf函数举例 9:把乘法口诀表输出到d:\abc.txt文件中。见程序D13_8.c。注意:程序中若把p换成stdout结果如何? 10:假定e:\abc.txt文件的内容按如下形式安排,把其内容读出,显示到屏幕上。见程序D13_9.c。 a,18,678.9 b,20,876.9 c,17,564.3 注意:行与行之间包含了两个不可见的字符,它们起到了回车换行的作用 其它读写函数——自己看书
4、文件的定位 文件中设有一个位置指针,在创建或打开一个只读文件时,文件的位置指针总是指向文件的开始;在对文件进行添加操作时,文件的位置指针总是指向文件的末尾。 对于一个文件,可以顺序读写,也可以随机读写。 所谓顺序读写,是每读一个数据后,位置指针自动向后移动一个位置。 所谓随机读写,是读写完一个数据后,重新定位位置指针,并在新位置上继续读写。 定位位置指针可以由文件定位或查找函数来实现。
4、文件的定位 文件指针重定位函数rewind() 调用形式:rewind(fp); 作用:使文件的位置指针重新指向文件头。 说明:该函数无返回值。
4、文件的定位 移动位置指针函数fseek(): 使用格式:fseek(文件指针,位移量,起始点); 作用:随机改变文件位置指针的当前位置。 说明: 1、调用成功返回值为0,失败返回非0数。 2、起始点的表示如课本P324表13.2所示。 3、位移量是以起始点为起点,向前或向后移动的字节数。C语言要求位移量为long型数据。 例如: fseek(fp,40L, 0); /*将位置指针从文件头向后移动40个字节*/ fseek(fp,4L, 1); /*将位置指针从文件当前位置向后移动4个字节*/ fseek(fp,-20L, 2); /*将位置指针从文件尾向前移动20个字节*/
12:把6个学生的有关情况送到指定的文件中,并在屏幕输出1、3、5个学生的情况。见D13_11.c 11:把从键盘输入的任意内容送到文件abc.txt中(直到输入#结束),然后把文件内容显示在屏幕上。见程序D13_10.c 12:把6个学生的有关情况送到指定的文件中,并在屏幕输出1、3、5个学生的情况。见D13_11.c
练习 1、若fp是指向某文件的指针,且已读到此文件的末尾,则库函数feof(fp)的返回值是(C) A)EOF B)0 C)非零值 D)NULL 2、若要打开A盘上user子目录下名为abc.txt的文本文件进行读、写操作,下面符合此要求的函数调用是(B) A)fopen(“A\user\abc.txt”,”r”); B)fopen(“A\user\abc.txt”,”r+”); C)fopen(“A\user\abc.txt”,”rb”); D)fopen(“A\user\abc.txt”,”w”); 3、在C程序中,可把整型数以二进制形式存放到文件中的函数是(A) A)fprintf函数 B)fread函数 C)fwrite函数 D)fputc函数
练习 4、以下程序用来统计文件中的字符个数,请填空。 #include”stdio.h” main() {FILE *fp; long num=0L; if((fp=fopen(“filenae.dat”,”r”)==NULL) {printf(“open error\n”); exit(0);} while( ) {fgetc(fp); num++;} printf(“num=%ld\n”,num-1); fclose(fp); } !feof(fp)
练习 5、以下程序把从终端读入的文本(用@作为文本结束标志)输出到一个名为bi.dat的新文件中,请填空。 #include”stdio.h” main() {FILE *fp; char ch; if((fp=fopen( )==NULL) {printf(“open error\n”); exit(0);} while((ch=getchar( ))!=‘@’) {fputc(ch,fp);} fclose(fp); } “bi.dat”, ”w”
作业: 1、课后作业第10和12题 2、输出如下杨辉三角,把输出结果放到一个文件中。 1 1 1 1 2 1 3 3 1 1 4 6 4 1 ……………………