对文件的操作包括打开文件,读文件,写文件,关闭文件和删除文件等操作.对文件进行操作之前,必须先打开该文件;使用结束后,应立即关闭,以免数据丢失.C语言规定了标准输入/输出函数库,用fopen函数打开一个文件,用fclose函数关闭一个文件.
1.文件打开函数fopen
所谓打开文件,是在程序和文件之间建立起联系,把所需要操作的文件的有关信息,如文件名,文件操作方式等通知给程序.实质上,打开文件表示给用户指定的文件在内存中分配一段FILE结构的存储单元,并将该结构的指针返回给用户程序,此后用户程序就可用此FILE指针来实现对指定文件的操作.
fopen()函数的一般调用形式为:
FILE *fp;
Fp = fopen(char *filename,char *mode);
fopen()函数打开一个filename指向的文件,文件操作方式由mode的值决定,将函数调用后的返回值赋给FILE类型的指针变量fp,这样fp就指向了文件filename.
例如:
FILE *fp;
fp=fopen(“datafile.dat”,”r”);
表示用只读方式打开名为datafile.dat的文件,并把文件的首地址赋给指针变量fp.一般文件名需要用双引号括起来,文件名中也可以包含用双反斜线”\\”隔开的路径名.
例如:
fp=fopen(“c:\\cfiles\\datafile.dat”,”r”);
C语言文件操作方式
文件操作方式 | 含义 |
r | 为只读打开一个字符文件 |
w | 为只写打开一个字符文件 |
a | 打开字符文件,指向文件尾,追加数据 |
rb | 为只读打开一个二进制文件 |
wb | 为只写打开一个二进制文件 |
ab | 打开一个二进制文件,以向文件追加数据 |
r+ | 以读写方式打开一个已存在的字符文件 |
w+ | 为读写建立一个新的字符文件 |
a+ | 为读写打开一个字符文件,进行追加 |
rb+ | 为读写打开一个二进制文件 |
wb+ | 为读写建立一个新的二进制文件 |
ab+ | 为读写打开一个二进制文件进行追加 |
[说明]
用”r”方式打开的文件必须是已经存在的文件,否则出错.用”w”方式打开的文件可以存在,也可以不存在.如果不存在该文件,则在打开时新建立一个以指定的名字命名的文件,用”a”方式打开的文件必须也是存在的,否则将出错.
如果不能实现”打开”的任务,fopen函数将会带回一个出错信息.出错的原因可能是:
1.用”r”方式打开一个并不存在的文件
2.磁盘出故障
3.磁盘已满无法建立新文件等.
此时函数将带回一个空指针值NULL.
常用下面的方法打开一个文件:
if((fp=fopen(“filename”,”r”))==NULL)
{
printf(“不能打开这个文件\n”);
exit(0);
}
2.文件关闭函数fclose()
程序对文件的读写操作完成后,必须关闭文件.这是因为对打开的磁盘文件进行写入时,若文件缓冲区的空间未被写入的内容填满,这些内容不会自动的写入到打开的文件中,从而导致内容丢失.只有对打开的文件进行关闭操作时,停留在文件缓冲区的内容才能写到磁盘文件上去,从而保证了文件的完整性.
所谓”关闭”就是指文件指针变量不指向该文件,也就是断开文件指针变量和文件之间的联系,此后不能再通过该指针对原来与其相联系的文件进行读写操作.除非再次打开,使该指针变量重新指向该文件.
关闭标准文件用fclose函数.一般调用形式为:
fclose(FILE *stream);
例如:
fclose(fp);
它表示该函数关闭了FILE 结构指针变量fp对应的文件.若成功的关闭了文件,则返回一个0值,否则返回一个非0值.
测试关闭文件成功与否的程序段如下:
if(fclose(fp) != 0)
{
printf(“不能关闭该文件.\n”);
exit(0);
}
else
printf(“文件被关闭了.\n”);
3.文件字符读函数fgetc()
从指定的磁盘文件读取一个字符,该文件必须是以读或读写方式打开,其调用形式为:
fgetc(FILE *stream);
例如:
ch = fgetc(fp);
它表示函数从指针变量fp所指定的文件中读取一个字符并赋给变量ch,fgetc函数的值就是该字符.若执行fgetc函数时遇到文件结束符EOF,则函数返回值”-1”给ch.注意,这个”-1”并不是函数读入的字符值,而是因为没有一个字符的ASCII码为”-1”.
从一个磁盘文件顺序读入字符并在屏幕上显示出来,程序段如下:
ch = fgetc(fp);
while(ch != EOF)
{
putchar(ch);
ch = fgetc(fp);
}
ANSI C提供了一个feof()函数来判断文件是否真的结束,feof(fp)用来测试fp指向的文件当前状态是否为”文件结束”.如果是文件结束,函数feof(fp)值为1(真),否则为0(假).
4.文件字符写函数fputc
把一个字符写到磁盘文件中去,其调用形式为:
fputc(char ch,FILE *stream);
例如:
fputc(ch,fp);
其中,ch是要输出的字符,它可以是一个字符常量,也可以是一个字符变量.fp是文件指针变量.fputc(ch,fp)函数的功能是将字符ch输出到fp所指向的文件中去.fputc函数也返回一个值,输出成功则返回值就是输出的字符,如果输出失败,则返回一个EOF.
[例题]
读出磁盘文件datafile.txt中的内容,将它们显示在屏幕上.
[程序代码]
#include <stdio.h>
#include <stdlib.h>
void main()
{
FILE *fp;
char ch;
if((fp = fopen(“datafile.txt”,”r”)) == NULL)
{
printf(“文件不能打开!\n”);
exit(0);
}
while(fp != EOF)
{
fputc(ch,stdout); //把字符输出到屏幕上
}
fclose(fp);
}
从键盘输入字符,逐个把它们送到磁盘中,直到输入一个”#”为止.
[程序代码]
#include <stdio.h>
#include <stdlib.h>
void main()
{
FILE *fp;
char ch,filename[10];
printf(“请输入文件名\n”);
scanf(“%s”,filename);
if((fp = fopen(filename,”r”)) == NULL)
{
printf(“不能打开文件!\n”);
exit(0);
}
printf(“请输入数据:”);
ch = getchar();
while(ch != ‘#’)
{
fputc(ch,fp);
putchar(ch);
ch = getchar();
}
fclose(fp);
}
5.文件字符串读函数fgets
其调用的一般形式是:
*fgets(char *str,int n,FILE *stream);
功能:从指针stream所指定的文件中读取n-1个字符,把它送到由指针str指向的字符数组中.
例如:
fgets(databuf,6,fp);
将fp指定的文件中的5个字符读到databuf内存区中.databuf可以是定义的字符数组,也可以是动态分配的内存区.若在读入n-1个字符完成之前就遇到换行符’\n’或文件结束符EOF,也将停止读入,但将遇到的换行符’\n’也作为一个字符送入字符数组中.fgets()在读入字符串之后会自动添加一个串结束符’\0’,因此送入字符数组中的字符串包括’\0’在内最多为n个字节.
fgets函数执行完后,返回一个指向该串的指针,即字符数组的首地址.如果读到文件尾或出错,则返回一个空值NULL.
6.文件字符串写读函数fputs
其调用的一般形式为:
fputs(char *str,FILE *stream);
功能: fputs函数把由str指针指明的字符数组中的字符串写入由stream指针指定的文件中.该字符串以空字符’\0’结束,但此字符将不写入到文件中去.str指向的字符串也可以用数组名代替,或用字符串常量代替.正确执行后,将返回写入的字符数,当出错时将返回”-1”.
例如:
c=fputs(“computer”,fp2);
将computer写入fp2指向的文件中.
[例题]
从键盘输入若干行字符,把它们添加到磁盘文件datafile2.txt中
[程序代码]
#include <stdio.h>
#include <stdlib.h>
void main()
{
FILE *fp;
char buffer[64];
if((fp=fopen(“datafile.txt”,”a”)) == NULL)
{
printf(“文件不能打开!\n”);
exit(0);
}
while(strlen(fgets(buffer,64,stdin))>1)
{
fputs(buffer,fp);
fputs(“\n”,fp);
}
fclose(fp);
}
7.格式化读写函数fscanf和fprintf
在实际应用中,应用程序有时需要按照规定的格式进行文件的读写,这时可以利用C语言文件格式读写函数fscanf和fprintf来完成.fscanf和fprintf函数与scanf和printf函数相似,都是格式化读写函数,只有一点不同:fscanf和fprintf函数的读写对象不是终端而是磁盘文件.档文件指针变量定义为stdin和stdout时,这俩个函数的功能就和scanf时,这两个函数的功能就和scanf和printf函数相同.
格式化读写函数的调用的一般形式为:
fscanf(FILE *stream,char *format,<variable-list>);
fprintf(FILE *stream,char *format,<variable-list>);
其中,char *format表示输入输出格式控制字符串,格式控制字符串的格式说明与scanf函数和printf函数的格式说明完全相同;<variable-list>表示输入输出参数列表.
例如:
fprintf(fp,”%d,%6.2f”,i,t);
它的作用是将整形变量i和实型变量t按%d和%6.2f的格式输出到fp指向的文件上.
8.文件定位函数
实现随机文件读写操作,首先必须解决文件指针的定位问题.如果能将文件指针指向文件的任意位置,再利用前面所述的文件操作函数,就可以实现文件的随机读写操作.C语言提供的文件指针定位函数有3个.
(1)rewind函数
其函数的调用的一般形式为:
rewind(FILE *stream);
它的作用是把文件指针重新移到文件的开头.移动成功时,返回值为0,否则返回一个非0值.
(2)fseek函数
其函数的调用的一般形式为:
fseek(FILE *stream,long offset,int origin);
它的作用是使文件指针移动到所需的位置.stream指定所需操作的文件,origin指明是以什么地方为基准进行指针移动,起点位置有3种
指针起点位置及其代表符号
起始点具体位置 | 符号代表 | 数字代表 |
文件开始 | SEEH_SET | 0 |
文件当前位置 | SEEK_CUR | 1 |
文件末尾 | SEEK_END | 2 |
offset是位移量,是以origin为基准指针向前或向后移动的字节数.位移量的值如果为负,表示指针向后移动,为正,表示指针向前移动.
(3)ftell函数
其函数调用的一般形式为:
ftell(FILE *stream);
它的作用是得到流式文件中的当前位置,用相对于文件开头的位移量来表示.由于文件中的位置指针经常移动,不容易知道其当前位置,而用ftell函数可以得到当前位置.函数返回值为一个长整型的正整数,如果函数的返回值为”-1L”,表示出错.