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循环对其进行打印输出。