文件最基本的数据操作有两个:从文件中读取信息(读操作)和把信息存放到文件(写操作)。C语言为文件的读写操作定义了一系列的标准函数,它们都在stdio.h中说明。
1.文本文件的操作
(1).字符读写
字符读写函数是以字符(字节)为单位的,也就是每次可从文件中读出或写入一个字符。
l 读字符函数fgetc
该函数的功能是从指定的文件中读一个字符,函数调用的形式为:
字符变量=fgetc(文件指针);
例如:
ch=fgetc(fp);
其意义是从打开的文件fp中读取一个字符并送入ch中。
对于fgetc函数的使用有以下几点说明:
在fgetc函数调用中,读取的文件必须是以读或读写方式打开的。
读取字符的结果也可以不向字符变量赋值。例如:fgetc(fp); 但是读出的字符不能保存。
在文件内部有一个位置指针。用来指向文件的当前读写字节。在文件打开时,该指针总是指向文件的第一个字节。使用fgetc函数后,该位置指针将向后移动一个字节。因此可连续多次使用fgetc函数,读取多个字符。应注意文件指针和文件内部的位置指针不是一回事。文件指针是指向整个文件的,须在程序中定义说明,只要不重新赋值,文件指针的值是不变的。文件内部的位置指针用以指示文件内部的当前读写位置,每读写一次,该指针均向后移动,它不需在程序中定义说明,而是由系统自动设置的。
【例8-2】读入文件,将内容在屏幕上输出
#include<stdio.h>
int main()
{
FILE *fp;
char ch;
if((fp=fopen("d:\\C实例\\ccode1.txt","r+"))==NULL)
{
printf("\nCannot open file strike any key exit!");
getch();
exit(1);
}
ch=fgetc(fp);
while(ch!=EOF)
{
putchar(ch);
ch=fgetc(fp);
}
fclose(fp);
return 0;
}
程序运行结果:
hello everybody
good morning.
本实例是从文件中逐个读取字符,在屏幕上显示。定义文件指针fp,以读文本文件方式打开文件,并使fp指向该文件。如打开文件出错,给出提示并退出程序。程序先读出一个字符,然后进入循环,只要读出的字符不是文件结束标志(每个文件末有一结束标志EOF)就把该字符显示在屏幕上,再读入下一字符,每读一次,文件内部的位置指针向后移动一个字符,文件结束时,该指针指向EOF,执行本程序将显示整个文件。
l 写字符函数fputc
该函数的功能是把一个字符写入指定的文件中。函数调用的形式为:
fputc( 字符量,文件指针 );
其中,待写入的字符量可以是字符常量或变量,例如:
fputc('a',fp);
其意义是把字符a写入fp所指向的文件中。
对于fputc函数的使用也要说明几点:
1) 被写入的文件可以用写、读写、追加方式打开,用写或读写方式打开一个已存在的文件时将清除原有的文件内容,写入字符从文件首开始。
2) 如需保留原有文件内容,希望写入的字符以文件末开始存放,必须以追加方式打开文件。
3) 被写入的文件若不存在,则创建该文件。
4) 每写入一个字符,文件内部位置指针向后移动一个字节。
5) fputc函数有一个返回值,如写入成功则返回写入的字符,否则返回一个EOF。可用此来判断写入是否成功。
【例8-3】从键盘输入一行字符,写入一个文件。
#include<stdio.h>
int main()
{
FILE *fp;
char ch;
if((fp=fopen("d:\\C实例\\example.txt","w+"))==NULL)
{
printf("Cannot open file strike any key exit!");
getch();
exit(1);
}
printf("input a string:\n");
ch=getchar();
while(ch!='\n')
{
fputc(ch,fp);
ch=getchar();
}
fclose(fp);
return 0;
}
程序运行结果:
input a string:
hello world↙
写入example.txt文件之后如图8-1所示:
图8-1 exmample.txt文件
本实例以读写文本文件方式打开文件example.txt。从键盘读入一个字符后进入循环,当读入字符不为回车符时,则把该字符写入文件之中,然后继续从键盘读入下一字符。每输入一个字符,文件内部位置指针向后移动一个字节。写入完毕,该指针已指向文件末。
(2).字符串读写
l 读字符串函数fgets
该函数的功能是从指定的文件中读一个字符串到字符数组中,函数调用的形式为:
fgets(字符数组名,n,文件指针);
其中的n是一个正整数。表示从文件中读出的字符串不超过n-1个字符。在读入的最后一个字符后加上串结束标志'\0'。例如:
fgets(str,n,fp);
的意义是从fp所指的文件中读出n-1个字符送入字符数组str中。
对fgets函数有两点说明:
在读出n-1个字符之前,如遇到了换行符或EOF,则读出结束。
fgets函数也有返回值,其返回值是字符数组的首地址。
【例8-4】从example文件中读入一个含11个字符的字符串
#include<stdio.h>
int main()
{
FILE *fp;
char str[12];
if((fp=fopen("d:\\C实例\\example.txt","r+"))==NULL)
{
printf("\nCannot open file strike any key exit!");
getch();
exit(1);
}
fgets(str,12,fp);
printf("%s\n",str);
fclose(fp);
return 0;
}
程序运行结果:
hello world
本实例首先定义一个字符数组str共12个字节,在以读文本文件方式打开文件example.txt后,从中读出11个字符送入str数组,在数组最后一个单元内将加上'\0',然后在屏幕上显示输出str数组。
l 写字符串函数fputs
该函数的功能是向指定的文件写入一个字符串,其调用形式为:
fputs(字符串,文件指针);
其中字符串可以是字符串常量,也可以是字符数组名,或指针变量,例如:
fputs(“abcd“,fp);
其意义是把字符串“abcd”写入fp所指的文件之中。
【例8-5】在文件example中追加一个字符串。
#include<stdio.h>
int main()
{
FILE *fp;
char ch,st[20];
if((fp=fopen("d:\\C实例\\example.txt","a+"))==NULL)
{
printf("Cannot open file strike any key exit!");
getch();
exit(1);
}
printf("inputa string:\n");
scanf("%s",st);
fputs(st,fp);
rewind(fp); /*把文件内部位置指针移到文件首*/
ch=fgetc(fp);
while(ch!=EOF)
{
putchar(ch);
ch=fgetc(fp);
}
printf("\n");
fclose(fp);
return 0;
}
程序运行结果:
input a string:
filewrite↙
hello worldfilewirte
写入example.txt文件之后如图8-2所示:
图8-2 exmample.txt文件
本实例是在example文件末加写字符串,以追加读写文本文件的方式打开文件example,然后输入字符串,并用fputs函数把该串写入文件example。
【例8-6】将磁盘文件a.txt中的内容复制到文件b.txt中。
#include<stdio.h>
int main()
{
FILE*fpa,*fpb;
if((fpa=fopen("D:\\C实例\\a.txt","r"))==NULL)
{
printf("Cannot open file a.txt!\n!");
exit(0);
}
if((fpb=fopen("D:\\C实例\\b.txt","w"))==NULL)
{
printf("Cannot open file b.txt!\n!");
exit(0);
}
while(!feof(fpa))
fputc(fgetc(fpa),fpb);/*文件复制*/
if(fclose(fpa))
printf("Can not close file a.txt!\n");
if(fclose(fpb))
printf("Can not close file b.txt!\n");
return 0;
}
程序运行结果:
运行前a.txt文件如图8-3所示,运行后b.txt文件如图8-4所示。
(3).格式化读写
文件操作中也有指定格式的输入输出函数:fscanf()和fprintf(),它们除了对字符类型有效外,对数值类型也有效。
fscanf函数,fprintf函数与前面使用的scanf和printf 函数的功能相似,都是格式化读写函数。两者的区别在于fscanf函数和fprintf函数的读写对象不是键盘和显示器,而是磁盘文件。
这两个函数的调用格式为:
fscanf(文件指针,格式字符串,输入表列);
fprintf(文件指针,格式字符串,输出表列);
例如:
fscanf(fp,"%d%s",&i,s);
fprintf(fp,"%d%c",j,ch);
【例8-7】文件f1.txt中有学生的成绩,请分别读出,计算机其平均值并将存入文件f2.txt。
#include<stdio.h>
#include<stdlib.h>
int main()
{
floatscore,sum=0.0;
int n=0;
FILE*fp1,*fp2;
if((fp1=fopen("D://C实例//f1.txt","r"))==NULL)
{
printf("Cannot open file f1.txt!\n!");
exit(0);
}
if((fp2=fopen("D://C实例//f2.txt","w"))==NULL)
{
printf("Cannot open file f2.txt!\n!");
exit(0);
}
while(!feof(fp1))
{
fscanf(fp1,"%f",&score);
sum=sum+score;
n++;
}
fprintf(fp2,"%f",sum/n);
if(fclose(fp1))
printf("Can not close file a.txt!\n");
if(fclose(fp))
printf("Can not close file b.txt!\n");
return 0;
}
程序运行结果:
f1.txt文件中学生成绩如图8-5所示,运行后f2.txt文件评价成绩如图8-6所示。
图8-5 f1.txt文件中学生成绩 图8-6 f2.txt文件中平均成绩