3

我正在逐字节读取二进制文件,我需要确定是否达到了 eof。

feof() 不起作用,因为“仅在对不存在的字节进行读取请求时才设置 eof”。所以,我可以让我的自定义 check_eof 像:

if ( fread(&byte,sizeof(byte),1,fp) != 1) {
    if(feof(fp))
    return true;
}
return false;

但问题是,如果没有达到 eof,我的文件指针会向前移动一个字节。所以一个解决方案可能是使用ftell(),然后fseek()让它到正确的位置。

另一种解决方案可能是将字节提前缓冲在一些临时存储中。

有更好的解决方案吗?

4

5 回答 5

6

如果您一次读取一个字节,则惯用的方法是fgetc

int c;
while ((c = fgetc(fp)) != EOF) {
   // Do something.
}

然后你不应该需要处理feof.

于 2010-04-13T23:56:03.360 回答
3

我通常会做这样的事情:

int get_next_char(FILE* fp, char *ch)
{
    return fread(ch, sizeof(char),1, fp) == 1;
}

// main loop
char ch;
while (get_next_char(fp, &ch))
    process_char(ch);

if (!feof(fp))
    handle_unexpected_input_error(fp);
于 2010-04-13T23:27:32.940 回答
2

最好对代码进行结构化,以便尝试读取一些数据,如果由于到达文件末尾而导致读取不成功,则在此处处理(即参见Kristopher Johnson 的回答)。

如果您绝对讨厌这个,您可以使用ungetc将单个字符返回到流中,它将在下一次读取调用中可用:

int c = fgetc(fp);
if (c == EOF)
{
    // handle eof / error
}
else
{
    ungetc(c, fp);

    // the next read call is guaranteed to return at least one byte

}
于 2010-04-14T00:10:59.883 回答
0

我不清楚,但是如果您有兴趣在读取字节之前知道是否已达到 EOF,请将您的 feof() 测试放在 fread() 之前而不是之后。
实际上,如果我没看错,你甚至不想这样做:

return feof(fp) ? true : false;
于 2010-04-13T23:24:58.977 回答
0

我建议使用:

fseek(myFile, 0, SEEK_END);
fileLen = ftell(myFile);
fseek(myfile, 0, SEEK_SET);

首次打开文件时确定长度。然后将您的读取循环设置为从不读取结尾。您可以使用它ftell来确定您所在的位置,并与 fileLen 进行比较以确定您还需要走多远。

于 2010-04-13T23:25:34.770 回答