概述
在C语言文件输入和输出操作的学习心得(二)已经详细介绍了C语言文件输入的操作,但未介绍如何读取文件的操作。本文针主要通过比较两种文件读出的方法向大家介绍C语言文件输出的一些基本操作,并向大家提供两个实例以供参考。
fgetc()
相关函数:open, fread, fscanf, getc
头文件:include<stdio.h>
原型:int fgetc(FILE * stream);
【说明】
fgetc()从参数stream 所指的文件中读取一个字符. 若读到文件尾而无数据时便返回EOF。此函数与前文提及到的getchar()类似。
【返回值】
fgetc()会返回读取到的字符, 若返回EOF 则表示到了文件尾
stdout
stdout(standardoutput)标准输出,不是一个函数,而是一个由C语言的头文件已经定好并且可以直接使用的文件指针。只是方便操作输出,比如传给一个函数等等。这时函数的输出就不是输出到文件,而是传进来的stdout文件指针,即标准输出。
实例1
#include <stdio.h>
int main()
{
FILE *pFile;
char c;
pFile = fopen("test.txt", "r");
if(pFile == NULL)//文件指针为空时的措施
{
printf("can not open the file");
fclose(pFile);
return 0;
}
while(c!=EOF)
{
c = fgetc(pFile);//获取文件的字符
fputc(c,stdout);//显示读取的单个字符
}
fclose(pFile);//关闭文件
return 0;
}
【说明】
细心的读者会发现以上这个实例,和前文(二)的实例相似度很高。不同之处在于fopen()函数中的模式换成了读取模式(r);fputc()函数中,文件流的参数换成了stdout。把读取到的字符放进标准输出以后,系统会把这些字符打印出来,从而起到了读取的功能。
fgets()
相关函数:open, fread, fscanf, getc
头文件:include<stdio.h>
原型:har * fgets(char * s, int size, FILE * stream);
【参数】
s:字符型指针,指向用来存储字符的数组
size:存储数据的大小
stream:数据的来源文件
【说明】
fgets()用来从参数stream 所指的文件内读入字符并存到参数s 所指的内存空间, 直到出现换行字符、读到文件尾或是已读了size-1 个字符为止, 最后会加上NULL 作为字符串结束.
【返回值】
fgets()若成功则返回s 指针, 返回NULL 则表示有错误发生
fputs()
相关函数:fopen, fwrite, fscanf, fputc, putc
头文件:#include <stdio.h>
原型:int fputs(const char * s, FILE * stream);
【说明】
fputs()用来将参数s 所指的字符串写入到参数stream 所指的文件内.
【返回值】
若成功则返回写出的字符个数, 返回EOF 则表示有错误发生.
feof()
相关函数:fopen, fgetc, fgets, fread
头文件:#include <stdio.h>
原型:int feof(FILE * stream);
【说明】
feof()用来侦测是否读取到了文件尾, 尾数stream 为fopen()所返回之文件指针. 如果已到文件尾则返回非零值, 其他情况返回0.
【返回值】
返回非零值代表已到达文件尾.
实例2
#include <stdio.h>
int main()
{
FILE *pFile;
char c[32];//定义一个长度为32的字符数组
pFile = fopen("test.txt", "r");
if(pFile == NULL)//文件指针为空时的措施
{
printf("can not open the file");
fclose(pFile);
return 0;
}
while(!feof(pFile))
{
fgets(c,32,pFile);//一次从文件中读取32个字节
fputs(c,stdout);//一次显示32个字节
}
fclose(pFile);//关闭文件
return 0;
}
【说明】
实例2和实例1的形式相似。采用feof()函数判别文件是否结束,读取文件和输出文件分别采用fgets()函数和fputs()函数,其特点是一次可从文件中读取32字节。事实上,一次读取多少位数据可以根据开发者的需要改变size和存储数据。
二者比较
实例1和实例2虽然形式相似,但是它们之间最大的区别是程序的效率,这种效率区别尤其在读取大量数据时能够体现。
实例1采用fgetc()函数,每次只能读取1个字符,一次循环只能读取1个字符。实例2采用fgets()函数,每次能读取32个字符,一次循环能够读取32个字符。假如一个txt文件有3200个字节,采用fgetc()需要执行3200次循环,而采用fgets()只需执行1000次循环。举一个例子,如果将一个字符比作一个水滴,一个字符串比作一个水杯,一个文本文件比作一桶水。我们要用最短时间抽干这桶水,是用杯子快还是一滴一滴流快呢?
那么是不是我们把储存字符的数组定义得越大越好呢?其实也未必,因为定义一个数组的实质是在内存划分一块区域用来储存数据。在内存有限的时候我们分配内存时必须谨慎,不然会出现很多意想不到的bug。定义存储数组的长度需要根据效率以及内存空间选择一个折中的值。
其实,实现读取文件的实例还有很多,本文只提供其中两个实例作为参考。如有其他实例,欢迎各位朋友前来交流。