Я пытался понять некоторый основной код и был немного смущен следующим кодом
int main ()
{
FILE *fp;
int c;
int n = 0;
fp = fopen("file.txt","r");
if (fp == NULL)
{
perror("Error in opening file");
return(-1);
}
do
{
c = fgetc(fp);
if ( feof(fp) )
{
break ;
}
printf("%c", c);
} while(1);
fclose(fp);
return(0);
}
Может кто-нибудь объяснить мне, почему с имеет целочисленный тип, даже если он определяется fgetc(fp)
который, насколько мне известно, получает только следующий персонаж?
Учитывая, как именно этот код был написан, c
не должно быть типа int
— все равно будет работать, если c
были типа char
,
Большая часть кода, который читает символы из файла, должна (по крайней мере на начальном этапе) читать эти символы в int
хоть. В частности, часть базовой конструкции ввода / вывода в стиле C заключается в том, что getc
а также fgetc
может возвращать EOF в дополнение к любому значению, которое могло прийти из файла. То есть любое значение типа char
может быть прочитан из файла. getc
, fgetc
и т. д., может сигнализировать о конце файла, возвращая хотя бы одно значение, которое не будет/не может пришли из файла. Обычно это -1, но это не гарантировано. когда char
подписано (как это обычно бывает в настоящее время), вы можете получить значение из файла, который будет отображаться как -1, когда он был назначен char
, так что если вы зависите от возвращаемого значения для обнаружения EOF, это может привести к неправильному обнаружению.
Код, который вы включили в вопрос, просто копирует содержимое файла в стандартный вывод, по одному символу за раз. Используя возвращаемое значение EOF, мы можем немного упростить код, поэтому основной цикл выглядит так:
int c;
while (EOF != (c = fgetc(fp)))
printf("%c", c); // or: putchar(c);
Я полагаю, что некоторые могут найти это слишком кратким. Другие могут возражать против назначения внутри условия цикла. Я, по крайней мере, думаю, что это разумные и обоснованные аргументы, но это все же достаточно хорошо согласуется с дизайном библиотеки, что предпочтительнее.
Подпись fgetc
int fgetc (FILE * stream);
И о вернуть ценность fgetc
В случае успеха читаемое значение возвращается (повышается до значения int).
Тип возвращаемого значения int для размещения специального значенияEOF
, что указывает на неудачу.
Поэтому мы объявляем переменную как целое число. Как символ может быть без знака, который не может принимать отрицательное значение. Но реализация EOF
всегда отрицательно или очень часто -1
который можно использовать как сбой или конец файла. Так что это безопасно использовать целое число и может быть использовано как
int c;
while ((c = fgetc(fp))!=EOF){
//Code goes here
}