12.2 文件的打开与关闭
对文件进行读、写操作时,首先要解决的问题是如何把程序中读写的文件与磁盘上的实际数据文件联系起来,接着就应该“打开”文件,在使用结束之后关闭文件。
考点2 fopen()函数和fclose()函数
真考链接
考点2难度适中,属重点掌握内容。在选择题中考核概率为60%。在操作题中的考核概率为10%。
1. fopen()函数
在C语言中,在对文件进行各种具体的操作之前,首先要“打开文件”,把程序中要读、写的文件与磁盘上实际的数据文件联系起来。此时需要调用C语言提供的库函数fopen“打开”文件来实现这些联系。
fopen函数的一般调用形式为:
fopen(文件名,文件使用方式);
函数返回一个指向 FILE类型的指针。若函数调用成功,则返回一个FILE类型的指针,赋给文件指针变量fp,从而把指针fp与文件联系起来,在此调用之后,指针fp就指向了文件。
无论采用哪种使用方式,当打开文件时出现了错误,fopen函数都将返回NULL。最常用的文件使用方式及其含义如下。
(1)“r”。为读而打开文本文件。当指定这种方式时,对打开的文件只能进行“读”操作。若指定的文件不存在,则会出错。另外,比如去读一个不允许读的文件时,也会出错。
(2)“rb”。为读而打开一个二进制文件。其余功能与“r”相同。
(3)“w”。为写而打开文本文件。这时,如果指定的文件不存在,系统将用在fopen调用中指定的文件名建立一个新文件;如果指定的文件已存在,则将从文件的起始位置开始写,文件中原有的内容将全部消失。
(4)“wb”。为写而打开一个二进制文件。其余功能与“w”相似,但从指定位置开始写。
(5)“a”。为在文件后面添加数据而打开文本文件。这时,如果指定的文件不存在,系统将用在fopen调用中指定的文件名建立一个新文件;如果指定的文件已存在,则文件中原有的内容将保存,新的数据写在原有内容之后。
(6)“ab”。为在文件后面添加数据而打开一个二进制文件。其余功能与“a”相同。
(7)“r+”。为读和写而打开文本文件。采用这种方式时,指定的文件应当已经存在。既可以对文件进行读操作,也可对文件进行写操作,在读和写操作之间不必关闭文件。只是对于文本文件来说,读和写总是从文件的起始位置开始。在写新的数据时,只覆盖新数据所占的空间,其后的老数据并不丢失。
(8)“rb+”。为读和写而打开一个二进制文件。功能与“r+”相同。只是在读和写时,可以由位置函数设置读和写的起始位置,也就是说不一定从文件的起始位置开始读和写。
(9)“w+”。首先建立一个新文件,进行写操作,随后可以从头开始读。如果指定的文件已存在,则原有的内容将全部消失。
(10)“wb+”。功能与“w+”相同,只是在随后的读和写时,可以由位置函数设置读和写的起始位置。
(11)“a+”。功能与“a”相同,只是在文件尾部添加新的数据之后,可以从头开始读。
(12)“ab+”。功能与“a+”相同,只是在文件尾部添加新的数据之后,可以由位置函数设置读的起始位置。
注意:这些指针是常量,而不是变量,因此不能重新赋值。
2. fclose()函数
在C语言中,对文件的读(写)等具体操作完成之后,必须将它关闭。关闭文件可调用库函数fclose来实现。
一般地,fclose函数的调用形式如下:
fclose(文件指针)
若对文件的操作方式为“读”方式,则经以上函数调用之后,要使文件指针与文件脱离联系。可以重新分配文件指针去指向其他文件。若对文件的操作方式为“写”方式,则系统首先把该文件缓冲区中的剩余数据全部输出到文件中,然后使文件指针与文件脱离联系。由此可见,在完成对文件的操作之后,应当关闭文件;否则文件缓冲区中的剩余数据就会丢失。
当执行关闭操作后,成功则函数返回0,否则返回非0。
小提示
打开文件时设定的文件使用方式与后面对该文件的实际使用方式不一致时,会导致系统产生错误。
在C语言中,当开始运行一个C程序时,系统将会自动打开3个文件,分别是标准输入文件、标准输出文件和标准出错文件,并规定相应的文件指针为stdin、stdout、stderr,它们已在stdio.h头文件中进行了说明。通常,stdin和键盘连接、rtdout和rtderr与终端屏幕连接。
常见问题
调用fopen 函数时,文件的使用方式为“rb+”,则此函数有何功能?
此函数为读和写而打开一个二进制文件。功能与“r+”相同。只是在读和写时,可以由位置函数设置读和写的起始位置,也就是说不一定从文件的起始位置开始读和写。
真题精选
【例1】下述关于C语言文件操作的结论中,( )是正确的。
A.对文件操作必须先关闭文件
B.对文件操作必须先打开文件
C.对文件操作顺序无要求
D.对文件操作前必须先测试文件是否存在,然后再打开文件
【答案】 B
【解析】本题考查文件操作的一般规则。对文件进行读写操作之前必须先打开文件,打开文件意味着将文件与一个指针相连,然后才能通过指针操作文件。通过打开文件也可以测试文件是否存在,例如,若文件不存在,则打开此文件时文件指针的值为0。况且,若为新创建文件,而打开文件进行写操作时,源文件根本不存在,此时更不必测试文件是否存在。总之,文件操作前并不是必须先测试文件是否存在,然后再打开文件。
【例2】如果需要打开一个已经存在的非空文件“FILE”进行修改,正确的打开语句是( )。
A.fp=fopen("FILE", "r"); B.fp=fopen("FILE", "ab+");
C.fp=fopen("FILE", "w+"); D.fp=fopen("FILE", "r+");
【答案】D
【解析】此题考查文件打开方式对文件操作的影响。由于对打开文件进行修改,可见选项A是错误的,因为用此种方式打开时,只能读,不能写,当然无法修改。选项B是以追加方式“ab+”打开文件进行读写的。以这种方式打开时,新写入的数据只能追加在文件原有内容之后,但可以读出以前的数据。换言之,以“ab+”或“a+”方式打开文件后,对于写操作,文件指针只能定位在文件的原有内容之后,但对于读操作,文件指针可以定位在全文件范围内,可见,按此种方式打开文件不能实现文件内容的修改。选项C以“w+”方式打开文件,此时,源文件中已存在的内容都被清除。但新写入文件的数据可以被再次读出或再次写入,故也不能实现对文件的修改。只有以“r+”方式打开文件时,才允许将文件原来数据读出,也允许在某些位置上再写入,从而实现对文件的修改。
【例3】下列给定程序中,函数fun()的功能是:将自然数1~10及其平方根写到名为myfile3.txt的文本文件中,然后再按顺序读出显示在屏幕上。
请在程序标号处填入正确的内容,使程序得出正确的结果。
注意:部分源程序给出如下。
不得增行或删行,也不得更改程序的结构。
试题程序
#include <math.h>
#include <stdio.h>
int fun(char *fname)
{ FILE *fp;int i,n;float x;
if((fp=fopen(fname,"w"))==NULL)
return 0;
for(i=1;i< =10;i++)
fprintf(【1】,"% d % f\n",i,sqrt ((double)i));
printf("\nSucceed!!\n");
【2】;
printf("\nThe data in file:\n");
if((fp=fopen(【3】,"r"))==NULL)
return 0;
fscanf(fp,"% d% f",&n,&x);
while(!feof(fp))
{ printf("% d % f\n",n,x);
fscanf(fp,"% d% f",&n,&x);
}
fclose(fp);
return 1;
}
main()
{ char fname[] ="myfile3.txt";
fun(fname);
}
【答案】【1】 fp 【2】 fclose(fp) 【3】 fname
【解析】本题考查文件的相关操作。fprintf函数与printf函数功能相似,区别在于fprintf函数的对象不是键盘和显示器,而是磁盘文件;文件打开和关闭函数fopen和fclose的使用。
标号【1】:fprintf函数的形式是:fprintf(文件指针,格式字符串,输出表列);,所以填入文件指针fp。
标号【2】:文件一旦使用完毕,应使用关闭函数fclose将文件关闭,以避免发生文件数据丢失等错误。
标号【3】:fopen函数用来打开一个文件,其一般形式为:文件指针名=fopen(文件名,使用文件方式);,因此应填入文件名fname。