8.3 读写函数的选用原则
本章第8.1节提过,对文件的操作主要分为4个步骤,前面讲解了打开和关闭操作,接下来介绍有关文件的读写操作。对文件的读写操作可以按以下4条原则来选取函数。
1.按照字符进行读写
先来看按照字符进行读写操作的两个函数:fputc和fgetc。
(1)fputc函数
int fputc(int ch,FILE*fp);
功能:送一个字符到指定的文件中。
返回值:写入成功则返回写入的字符,失败则返回EOF。
(2)fgetc函数
int fgetc(FILE*fp);
功能:从文件指针fp指向的文件中读取一个字符。
返回值:返回读取的一个字节。如果读到文件末尾就返回EOF。
接下来通过代码来看上述两个函数的使用。
include<stdio.h>
int main()
{
FILE*fpin;
fpin=fopen("text.txt","w");
if(NULL==fpin)
{
printf("打开失败!\n");
return 0;
}
int i;
char a=0x41;
char b;
for(i=0;i<26;i++)
{
b=a+i;
fputc(b,fpin);
}
fclose(fpin);
return 0;
}
在上面的代码中,通过fput函数向文件text.txt中写入26个大写的英文字母,运行程序后,打开当天目录下的文件text.txt发现成功实现了字符的写入。接下来通过fgetc函数将上面写入文件的字符读出来并保存到一个数组中,最后将其打印输出,代码如下:
include<stdio.h>
int main()
{
FILE*fpout;
fpout=fopen("text.txt","r");
if(NULL==fpout)
{
printf("打开失败!\n");
return 0;
}
int i=0;
char a[26];
char c;
while((c=fgetc(fpout))!=EOF)
{
a[i]=c;
printf("%c",a[i]);
i++;
}
fclose(fpout);
return 0;
}
运行结果:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
从上面的运行结果可以看出,成功地实现了将text.txt文件中的数据读到数组a中。在上面的代码中,采用的是EOF来判断当前对打开的文本文件的读操作是否到达文件的末端。
2.按照字符串进行读写
按照字符串进行读写操作的两个函数为:fgets和fputs。
(1)fgets函数
charfgets(chars,int size,FILE*fp);
功能:该函数从参数fp所指的文件内读入字符并存到参数s所指的内存空间,直到出现换行字符、读到文件尾或已读了size-1个字符为止,最后加上NULL标示字符串结束。
返回值:读写成功则返回s指针,否则返回NULL。
(2)fputs函数
int fputs(charstring,FILEfp);
功能:将string所指向的字符串写入fp所指定的文件中去。
返回值:读写成功返回为0,否则返回非0值。
接下来通过代码介绍上述两个函数的使用。
include<stdio.h>
int main()
{
FILE*fpin;
char*string[4]={"Hello world!","Hello Bigloomy!","Happy","Gloomy"};
fpin=fopen("text.txt","w");
if(NULL==fpin)
{
printf("打开失败!\n");
return 0;
}
int i=0;
for(i=0;i<4;i++)
fputs(string[i],fpin);
fclose(fpin);
return 0;
}
在上面的代码中,通过fputs函数向打开的文件中一次输入一个字符串。运行代码,打开当前目录下的text.txt,发现其保存的数据信息与所输入的完全一致。接下来再看如何通过fgets函数从上面的文件中获取写入的字符串。
include<stdio.h>
int main()
{
FILE*fpout;
char string[4];
fpout=fopen("text.txt","r");
if(NULL==fpout)
{
printf("打开失败!\n");
return 0;
}
while(!feof(fpout))
{
fgets(string,4,fpout);
printf("%s",string);
}
fclose(fpout);
return 0;
}
运行结果:
Hello world!Hello Bigloomy!HappyGloomy
上面的运行结果与此前写入的数据信息完全一致,但是需要留意fgets函数,其中的参数n并不是每次读取的字符数,每次读取的字符数是n-1,最后再添加一个回车符。
3.按照磁盘文件进行读写
按照磁盘进行读写操作的两个函数为:fprintf和fscanf。
(1)fprintf函数
int fprintf(FILEfp,charformat[,argument])
功能:fprintf()函数根据指定的format(格式)写入(参数)到由fp(文件指针)指定的文件中,fprintf()只能和printf()一样工作。
返回值:读写成功则返回输出的字符数,错误则返回负数。
(2)fscanf函数
int fscanf(FILEfp,charformat,[argument……]);
功能:向fp文件指针所指向的文件中写入字符。
返回值:读写成功则返回实际读出的数据个数,若文件中没有数据则返回0,失败则返回EOF。
接下来通过代码来看上述两个函数的使用。
include<stdio.h>
int main()
{
FILE*fpin;
fpin=fopen("text.txt","w");
if(NULL==fpin)
{
printf("打开失败!\n");
return 0;
}
int i,j;
for(i=1;i<=9;i++)
{
for(j=1;j<=i;j++)
{
fprintf(fpin,"%d X%d=%d\t",j,i,j*i);
}
fprintf(fpin,"\n");
}
fclose(fpin);
return 0;
}
在上面的代码中,采用fprintf函数向打开的text.txt文件中输入九九乘法表,运行程序后打开text.txt,发现已经成功在文件中输入了一个九九乘法表。接下来通过fscanf函数对上面的text.txt文件进行读操作,并且将读取的九九乘法表打印出来。
include<stdio.h>
int main()
{
FILE*fpout;
fpout=fopen("text.txt","r");
if(NULL==fpout)
{
printf("打开失败!\n");
return 0;
}
int i,j;
int a,b,c;
for(i=1;i<=9;i++)
{
for(j=1;j<=i;j++)
{
fscanf(fpout,"%d×%d=%d\t",&a,&b,&c);
printf("%d×%d=%d",a,b,c);
}
printf("\n");
}
fclose(fpout);
return 0;
}
运行结果:
1×1=1
1×2=2 2×2=4
1×3=3 2×3=6 3×3=9
1×4=4 2×4=8 3×4=12 4×4=16
1×5=5 2×5=10 3×5=15 4×5=20 5×5=25
1×6=6 2×6=12 3×6=18 4×6=24 5×6=30 6×6=36
1×7=7 2×7=14 3×7=21 4×7=28 5×7=35 6×7=42 7×7=49
1×8=8 2×8=16 3×8=24 4×8=32 5×8=40 6×8=48 7×8=56 8×8=64
1×9=9 2×9=18 3×9=27 4×9=36 5×9=45 6×9=54 7×9=63 8×9=72 9×9=81
从上面的运行结果中可以看到,成功地实现了通过fscanf函数将文件text.txt中的数据读取出来,并且采用printf函数进行了打印输出。
4.按组进行读写
按组进行读写操作的两个函数为:fwrite和fread。
fwrite函数如下:
size_t fwrite(const voidbuffer,size_t size,size_t count,FILEfp);
功能:将一个数据块写入fp文件指针指向的文件中,其中,buffer参数是所要输出数据的地址,size是每次所要写入的字节数,count是所要写入的次数,fp是所要写入的目标文件指针。
返回值:读写成功则返回写入的字节数。
fread函数如下:
size_t fread(voidbuffer,size_t size,size_t count,FILEfp);
功能:从fp文件指针所指向的文件中读取一个数据块。
返回值:buffer是所要读入内存中的地址,size是所要读取的数据块的字节数,而count是所要读取的数据块的个数。
下面看上述两个函数的使用。
include<stdio.h>
define N 4
struct stu
{
char name[10];
char nu[10];
int score;
}st[N]={{"李小鹏","21009011",326},
{"张迪蝶","21009012",562},
{"彭晓敏","21009013",456},
{"王梅梅","21009014",258}
};
int main()
{
FILE*fpin;
fpin=fopen("bina.txt","w");
if(NULL==fpin)
{
printf("打开失败!\n");
return 0;
}
int i;
for(i=0;i<N;i++)
{
fwrite(&st[i],sizeof(st[i]),1,fpin);
}
fclose(fpin);
return 0;
}
在上面的代码中,通过函数fwrite向指定的文件中输入数据,打开文件后发现使用该函数存储的数据与前面介绍的函数都不同。我们不能主观地判断存储的结果是否正确,为了验证结果的正确与否,接下来用fread函数来读取刚才存储的信息,并将其打印出来看是否成功地实现了fwrite的写入,同时也查看一下fread函数的使用情况,代码如下:
include<stdio.h>
define N 4
struct stu
{
char name[10];
char nu[10];
int score;
};
int main()
{
FILE*fpout;
fpout=fopen("bina","rb");
if(NULL==fpout)
{
printf("打开失败!\n");
return 0;
}
struct stu ss[4];
fread(ss,sizeof(ss[1]),N,fpout);
int i;
for(i=0;i<N;i++)
{
printf("%s\t%s\t%d\n",ss[i].name,ss[i].nu,ss[i].score);
}
fclose(fpout);
return 0;
}
运行结果:
李小鹏21009011 326
张迪蝶21009012 562
彭晓敏21009013 456
王梅梅21009014 258
从上面的运行结果可以发现,输出的就是前面的代码中采用fwrite函数写入的数据,同时通过fread函数一次性从指定的文件中读取出了存储的数据信息。读取的信息存储在ss数组中,接下来通过一个for循环对其进行打印输出。