在课堂上,我遇到了以下代码片段
for (numlines = 0, (fp=fopen("thefile",'r')); feof(fp); numlines++ ) {
fgets(fp, buffer, sizeof(buffer), fp);
...
}
在for循环头中,可以初始化numlines
和fp
这两个东西,对吧?
然后在for循环的主体中,
fgets(fp, buffer, sizeof(buffer), fp);
这就是让我困惑的地方。我以为fgets()
函数采用了这些参数
char *fgets(char *str, int n, FILE *stream)
知道每秒2帧在做什么吗?
你知道每秒2帧在做什么吗?
这是一个拼写错误——作者在写那句话时显然搞错了。编译器应该抱怨该调用。
它还应该抱怨fp=fopen("thefile",'r')
——第二个参数应该是"r"
,而不是'r'
。
我认为在这两行代码中至少有3个额外的问题:
- 作者在读取文件之前没有验证
fopen
调用是否成功 -
千万不要使用
feof
作为循环条件-它不会返回true,直到之后你试图读取超过文件末尾,这意味着你会经常循环一次,它不会捕捉到实际的读取错误 - 在上一个的基础上,您应该检查
fgets
的结果以确保它成功
IMO,该代码应写成
fp = fopen( "thefile", "r" );
if ( !fp )
{
// unable to open file, bail out here
}
for ( numlines = 0; fgets( buffer, sizeof buffer, fp ); numlines++ )
{
// do stuff with buffer
}
if ( feof( fp ) )
{
// normal end of file
}
else
{
// error on read, handle as appropriate
}
虽然可以调用fopen
作为for
循环中初始值设定项表达式的一部分,但您应该将其作为一个单独的操作来执行,并确保在进入循环之前成功。
检查fgets
的结果作为循环条件。如果返回NULL
,则检查原因是EOF还是读取错误。