从文件中用fgets读取一行内容时, 如何设定缓冲区的大小, 是一个值得考虑的问题. 以下是我读eash源码中看到的一个函数, 在需要一次读入一整行很长的内容时可以参考下.
static char *local_getline(char *zPrompt, FILE *in){
char *zLine;
int nLine;
int n;
int eol;
if( zPrompt && *zPrompt ){
printf("%s",zPrompt);
fflush(stdout);
}
nLine = 100;
zLine = malloc( nLine );
if( zLine==0 ) return 0;
n = 0;
eol = 0;
while( !eol ){
if( n+100>nLine ){
nLine = nLine*2 + 100;
zLine = realloc(zLine, nLine);
if( zLine==0 ) return 0;
}
if( fgets(&zLine[n], nLine - n, in)==0 ){
if( n==0 ){
free(zLine);
return 0;
}
zLine[n] = 0;
eol = 1;
break;
}
while( zLine[n] ){ n++; }
if( n>0 && zLine[n-1]=='\n' ){
n--;
zLine[n] = 0;
eol = 1;
}
}
zLine = realloc( zLine, n+1 );
return zLine;
}
这里有一个不怎么好的地方是, 每次调用函数都需要动态分配内存. 如果设定固定大小的缓冲区, 选择设一个很大的值得话, 比较浪费也很难找到一个合适的大值. 折中一下, 设定一个一般字符串的长度限制为缓冲区的大小, 每次读取后, 再判断下是否到达行末, 如果没有到达, 再利用上面的方法动态分配缓冲区. 虽然在遇到长的行时比上面的代码会多一些负担, 但是实际情况中, 很长的行的概率是非常低的,因此会节省不少时间.