feof () в обработке файла C - PullRequest
       13

feof () в обработке файла C

3 голосов
/ 14 апреля 2010

Я читаю двоичный файл побайтово, мне нужно определить, достиг или нет eof.

feof () не работает, так как «eof устанавливается только при выполнении запроса на чтение несуществующего байта». Итак, я могу сделать свой собственный check_eof, например:

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

Но проблема в том, что если eof не достигнут, мой указатель файла перемещается на байт вперед. Таким образом, решение может заключаться в использовании ftell(), а затем fseek(), чтобы вернуть его в правильное положение.

Другим решением может быть буферизация байта в некотором временном хранилище.

Есть ли лучшие решения?

Ответы [ 5 ]

6 голосов
/ 14 апреля 2010

Если вы читаете байт за раз, идиоматический способ сделать это - fgetc:

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

и тогда вам не нужно иметь дело с feof.

3 голосов
/ 14 апреля 2010

Я обычно делаю что-то вроде этого:

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);
2 голосов
/ 14 апреля 2010

Лучше структурировать ваш код так, чтобы вы пытались прочитать некоторые данные, и если чтение не удается из-за достижения конца файла, вы имеете дело с этим там (т.е. см. ответ Кристофера Джонсона ).

Если вы абсолютно ненавидите это, вы можете использовать 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

}
0 голосов
/ 14 апреля 2010

Я бы предложил использовать:

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

При первом открытии файла определить длину. Затем настройте цикл чтения так, чтобы он никогда не читался с конца. Вы можете использовать ftell, чтобы выяснить, где вы находитесь, и сравнить с fileLen, чтобы выяснить, сколько вам еще предстоит пройти.

0 голосов
/ 14 апреля 2010

Мне непонятно, но если вам интересно узнать, прежде чем читать байт, достигнут ли EOF, поставьте тест feof () перед fread (), а не после него.
на самом деле, если я читаю правильно, вы даже не хотите делать фред так:

return feof(fp) ? true : false;
...