一种可能性是动态分配缓冲区,然后根据需要增加它(例如,使用 realloc)。这可能需要为 fgets 编写一个包装函数,以检查它是否读取了整行(换行符存储在缓冲区中)。它还必须处理 EOF 条件。
这可能不言而喻,但使用 C 读取和解析具有可变宽度数据的文本文件是一项相当多的工作。这可能对您的情况没有意义,甚至是不可能的,但如果您可以使用 Ruby、Python、Perl、Awk 等,您可能可以在很短的时间内完成任务。您可以使用这些工具在几行代码中完成可能需要一百行 C 的代码。它们非常适合读取和解析分隔的文本文件。例如,下面的 ruby 块逐行读取文本文件并用竖线将其分割:
File.open("myfile.txt") { |file|
while ( line = file.gets )
puts "line: #{line}"
a = line.split( /\|/ )
puts "array: #{a}"
end
}
只是为了好玩,这里有一个可能的实现,需要处理一些 TBD(错误检查)。主要问题(除了我没有看到的细微错误)将是解决缓冲区的释放问题,如果您没有完全阅读到 EOF。
int myReadLine // return non-zero if line returned, 0 on eof (see tbd below)
(
FILE *fp, // (I) open file handle for reading
char **buf, // (IO) buffer allocated by this function. It is freed by
// this function when EOF is hit. TBD: Should write a myFreeLine
// (for encapsulation purposes) to free this buffer for cases where
// you quit calling
int *len // (IO) current length of buffer pointed to by buf
)
{
char *ret;
char *pos;
int curlen;
int remaining;
if ( *len == 0 )
{
assert( *buf == NULL );
// pick a number out of the air. Could be app-specific. In debug
// it may be nice to start very small to force reallocs to exercise all
// code paths.
*len = 2;
// tbd: need error checking
*buf = (char*)malloc( *len * sizeof( char ));
}
pos = *buf;
remaining = *len;
while ( 1 )
{
ret = fgets( pos, remaining, fp );
if ( ret == NULL )
{
// tbd: should check if error occurred here. For now assuming eof
free( *buf );
*buf = NULL;
*len = 0;
return 0;
}
// check to see if we got the entire line.
curlen = strlen( *buf );
if ( (*buf)[curlen - 1] == '\n' ) // tbd: check for \r?
{
// apparently we got the whole line
// remove the end of line (at least that's what I would want)
(*buf)[curlen - 1] = '\0';
return 1;
}
else
{
// failed to get entire line
assert( curlen + 1 == *len );
// grow the buffer (tbd: realloc is a pain ... need error checking)
*len *= 2; // doubling is often a good plan
*buf = (char*)realloc( *buf, *len );
// set the "amount left" variables correctly for next iteration
remaining = *len - curlen;
pos = *buf + curlen;
}
} // while forever
// don't expect to get here
assert( 0 );
}
这是一个示例调用:
void readfile(char *filepath)
{
int len = 0;
char *buf = NULL;
FILE *fp=fopen(filepath,"rt");
while ( myReadLine( fp, &buf, &len ))
printf( "'%s'\n", buf );
fclose(fp);
}