fclose () всегда возвращает EOF

У меня есть функция, которая читает целые числа определенного формата из файла. Он отлично работает по желанию, но всякий раз, когда я пытался закрыть файл с помощью fclose (), fclose () всегда возвращает EOF.

Есть предложения, почему? Я студент и все еще учусь. Я поместил код ниже. Пожалуйста, дайте мне знать, если вам понадобится код "обработки". Спасибо :)

// Open the file
FILE *myFile = fopen(fileName, "r");
if(myFile == NULL){
    //Handle error
    fprintf(stderr, "Error opening file for read \n");
    exit(1);
}

while(myFile != EOF)
{
     // read and process the file
     // this part works.
}

// always returns EOF here. WHY?
if (fclose(myFile) == EOF) {
    // Handle the error!
    fprintf(stderr, "Error closing input file.\n");
    exit(1);
}
printf("Done reading the file.");

РЕДАКТИРОВАТЬ: Спасибо за все ответы. Извините, я не могу опубликовать код, так как это часть моей домашней работы. Я пытался получить некоторую помощь, я не прошу вас писать код для меня. По словам моего профессора, почтовый индекс является незаконным (поскольку другие студенты могут видеть и вероятно копировать, он сказал мне это именно так). Я могу выложить код только после воскресенья. А пока я постараюсь изменить свой код и избегать использования fscanf. Спасибо и мои извинения.


person blenzcoffee    schedule 04.08.2012    source источник
comment
См. stackoverflow.com/questions/1954273/fclose-return-value-check   -  person Inisheer    schedule 04.08.2012
comment
Это: while (myFile != EOF) неверно. myFile - указатель; EOF относится к типу int. Их сравнение почти наверняка приведет к диагностике компилятора, которую вы ни в коем случае не должны игнорировать, и, скорее всего, приведет к бесконечному циклу. Это заставляет меня думать, что while (myFile != EOF) на самом деле не в вашем коде. Покажите, пожалуйста, настоящий код.   -  person Keith Thompson    schedule 04.08.2012
comment
@keithThompson, который есть в моем коде, и он работает, как ни странно. Но я изменил его на while (! Feof (myFile)) только сейчас (после просмотра вашего комментария). Спасибо   -  person blenzcoffee    schedule 04.08.2012
comment
@KeithThompson, на самом деле проблема была в этом! код работает без ошибок. Можете ли вы разместить свой комментарий как сообщение, чтобы я мог отметить его как ответ? Спасибо   -  person blenzcoffee    schedule 04.08.2012


Ответы (5)


Этот:

while(myFile != EOF)

фактически незаконно (нарушение ограничения). Любой соответствующий компилятор C должен выдавать диагностику; gcc по умолчанию просто выдает предупреждение (которое квалифицируется как «диагностика»).

Если gcc выдал предупреждение, обратите на него внимание; gcc часто выдает предупреждения о вещах, которые, IMHO, следует рассматривать как фатальные ошибки. И если он не выдал вам предупреждения, вы, вероятно, вызываете его с параметрами, отключающими предупреждения (что странно, потому что оно выдает это предупреждение по умолчанию). Хороший набор параметров для использования - -Wall -Wextra -std=c99 -pedantic (или измените параметр -std=..., чтобы применить другую версию стандарта, если хотите).

myFile относится к типу указателя, а именно FILE*. EOF относится к типу int и обычно расширяется до (-1). Вы не можете юридически сравнивать значение указателя с целочисленным значением (за исключением особого случая константы нулевого указателя, но здесь это не применяется).

Предполагая, что программа не отклонена, я бы ожидал, что это приведет к бесконечному циклу, поскольку myFile почти наверняка никогда не будет равно EOF.

Вы можете изменить его на

while (!feof(myFile))

но это может вызвать другие проблемы. Правильный способ определить конец файла при чтении из файла - использовать значение, возвращаемое любой функцией, которую вы используете для чтения данных. Обратитесь к документации по используемой функции, чтобы узнать, что она возвращает, когда обнаруживает конец файла или состояние ошибки. Функция feof() полезна для определения после завершения чтения, столкнулись ли вы с концом файла или с ошибкой.

person Keith Thompson    schedule 04.08.2012
comment
@dsutandi: Полезно прочитать документацию по любой функции, которую вы вызываете. - person Keith Thompson; 04.08.2012

Поскольку вы ничего не можете сделать с обычным файлом, открытым в режиме только для чтения, что могло бы вызвать ошибку fclose, у вас, скорее всего, есть ошибка в коде, который вы не показали, который нарушает структуру myFile.

Также тест myFile != EOF никогда не будет истинным, потому что вы установили его на возврат fopen, который никогда не даст вам EOF, и вы уже проверили его на NULL. Вы имели в виду что-то вроде:

while((c = fgetc(myFile)) != EOF) {
    // do stuff
}
person msw    schedule 04.08.2012
comment
в коде, который я не показывал, я использую fscanf для чтения каждого целого числа. Я использую этот вызов fscanf в нескольких местах. Возможно ли быть ошибкой? - person blenzcoffee; 04.08.2012
comment
обычно fscanf является большим источником ошибок указателя для новичка в C, который часто передает указатели, которые не указывают на выделенное пространство. Это может легко повредить другие конструкции. - person msw; 04.08.2012
comment
@dsutandi Просто покажите весь свой код, а не заставляйте всех гадать. - person Jim Balter; 04.08.2012

Что сказал errno? добавьте это в свой код:

#include <errno.h>
#include <string.h>

if (fclose(myFile) == EOF) {
    // Handle the error!
    fprintf(stderr, "Error closing input file. and errno = %d, and error = %s\n", errno, strerror(errno));
    exit(1);
}

Надеюсь на эту помощь.

С Уважением.

person TOC    schedule 04.08.2012
comment
номер ошибки 0, и он говорит об ошибке чтения. Попробую тогда погуглить, что вызывает :) Спасибо! - person blenzcoffee; 04.08.2012
comment
@dsutandi: Хорошо, если хочешь, можешь опубликовать свой код, и мы сможем помочь. - person TOC; 04.08.2012

while(myFile != EOF)
 {
 // read and process the file
 // this part works.
 }

Если эта часть в порядке, тогда

fclose(myFile);

определенно вернет вам EOF. Поскольку цикл while завершается только myFile == EOF (это неправильное сравнение, не игнорируйте предупреждения). сравнение между указателем и int. Поскольку EOF - это макрос, определенный в файле stdio.h И согласно glibc это -1. Ваш цикл завершается, это означает, что ваш указатель myFile каким-то образом изменился на EOF. Это ваша ошибка.

просто просмотрите свой код, вы должны изменить указатель FILE myFile, который не должен быть перезаписан вами, поскольку он указывает на файловую структуру, которая используется для всех файловых операций.

ПРИМЕЧАНИЕ. myFile, который является указателем на файл, не должен использоваться как lvalue в любом операторе присваивания.

person rajesh6115    schedule 04.08.2012

Замените while(myFile != EOF){...} на while(!feof(myFile)){...}
myFile - это указатель на структуру FILE (адрес памяти). Не индикатор "конца файла".

person André A. G. Scotá    schedule 04.08.2012