分类: LINUX
2011-02-25 12:48:12
作者:王姗姗,讲师。
在标准IO中,对于文件的读写无非三种方式:
(1) 每次一个字符的I / O。
(2) 每次一行的I / O。
(3) 直接I / O。
似乎这些函数看起来很简单,但只有理解了这些函数,你才知道该如何使用,例如怎样来判断读取的文件是否结束,怎样来统计文件的行数,等等。
下面先来回顾下读取文件的三种方式,然后再举例看下怎样使用。
一次读或写一个字符,使用getc、fgetc或getchar。如果流是带缓存的,则标准I / O函数处理所有缓存。三个函数原型如下:
#include
int getc(FILE *fp) ;
int fgetc(FILE *fp) ;
int getchar(void);
三个函数的返回:若成功则为下一个字符,若已处文件尾端或出错则为E O F。强调的是不管是出错还是到达文件尾端,这三个函数都返回同样的值。为了区分这两种不同的情况,必须调用ferror()或feof()。
两个函数原型如下:
#include
Char *gets(char *s) ;
Char *fgets(char *s,int
size,FILE *steam)
两个函数返回:若成功则为buf,若已处文件尾端或出错则为null。这两个函数都指定了缓存地址,读入的行将送入其中。gets()从标准输入读,而fgets()则从指定的流读。
对于fgets(),必须指定缓存的长度为n。此函数一直读到下一个新行符为止,但是不超过n-1个字符,读入的字符被送入缓存,该缓存以null字符结尾。如若该行,包括最后一个新行符的字符数超过n-1,则只返回一个不完整的行,而且缓存总是以null字符结尾。对fgets()的下一次调用会继续读该行。
直接I / O使用的是fread。每次I /
O操作读某种数量的对象,而每个对象具有指定的长度。这个函数常用于从二进制文件中读一个结构。原型如下:
int fread(void * ptr,int
objsize,int objnum,FILE *fp);
这个函数返回:读的对象数。fputs()在遇到null字节时就停止,而在结构中可能含有null字节,所以不能使用每次一行函数实现这种要求,而fread能使我们一次读整个结构。
下面看下如何利用上面提到的标准IO读函数来判断你读取的文件是否结束以及如何来统计文件的行数。
1、判断文件结束有三种方式:
a) 当用fgetc(src)返回的int值为EOF时,读到文件的末尾
b) 当用fgets(p,1024,src)返回的指针为NULL时,读到文件的末尾
c) 当用fread(s,1,20,src)返回的个数小于20时,读到文件的末尾
实现起来简单明了,就不再细说。
2、统计文件的行数
a) 当用fgetc(src)返回的int值为’\n’时行数加一
b) 当用fgets(p,1024,src)返回的指针不为NULL时,你的缓冲即提供的p[1024]已经读到字符,这个时候实际上有两种情况,一种你读进来的字符长度小于1024个,这个时候一行结束,行数加一,另一种比较复杂,由于受自己定义的缓冲的限制,一次只能读进来1023个,如果恰好这个时候你刚好读完一行,那p[]1022]里存放的一定’\n’,如果不是,那你的一行还一定没有结束了。
程序如下:
Int n;
A)
While(fgetc(src)==’\n’)
N++;
B) while(fgets(p,1024,src)!=NULL)
{
If(strlen(p)<1024||p[1022]==’\n’)
N++;
}