Отношение стандартных значений и EOF в C

#c #printf #stdin #fopen #eof

#c #printf #stdin #fopen #eof

Вопрос:

В тесте на C были эти четыре вопроса, которые касаются fprintf и EOF. На самом деле они не были объяснены в разделе курса, связанном с этими вопросами, и я не могу найти хороших ответов на них в Интернете.

Является ли причиной сбоя чисел, напечатанных на экране, и / или компиляции результатом fprintf или его связи с EOF?

 #include <stdio.h> 

int main(void) { 
    int i; 
    i = fprintf(stdin,"Hello!"); 
    printf("%d",i == EOF); 
    return 0; 
} 
  

Ответ: программа выводит 1

 #include <stdio.h> 

int main(void) { 
    int i; 
    i = fprintf(stderr,"Hello!"); 
    printf("%d",i == EOF); 
    return 0; 
}
  

Ответ: программа выводит 0 в поток стандартного вывода

 #include <stdio.h> 

int main(void) { 
    FILE *f; 
    int i = fprintf(f,"Hello!"); 
    printf("%d",i == EOF); 
    return 0; 
}
  

Ответ: компиляция или выполнение завершаются с ошибкой

 #include <stdio.h> 

int main(void) { 
    FILE *f = fopen("file","w"); 
    int i = fprintf(f,"Hello!"); 
    printf("%d",i != EOF); 
    return 0; 
}
  

Ответ: программа выводит 1

Комментарии:

1. Ни один из этих результатов не указан языком. EOF требуется только отрицательное значение, но оно может быть любым отрицательным числом. Аналогично, fprintf() возвращает отрицательное число при получении ошибки, но оно также может быть любым отрицательным числом. Нет требования, чтобы эти отрицательные числа были одинаковыми.

2. Третий вызывает неопределенное поведение. Вы никогда не инициализировали f , поэтому вы не можете использовать его в качестве аргумента fprintf() .

3. @Barmar я вижу. почему i = fprintf(stdin,»Привет!»); возвращает отрицательный результат?

4. stdin открыт только для чтения, вы не можете записать в него, поэтому он выдает ошибку.

5. @Onederfoo «stdin открыт только для чтения», что, хотя и верно в большинстве случаев, не обязательно так.

Ответ №1:

EOF — это макрос, который очень часто равен -1.

  1. Q1 :
    • stdin является входным потоком. Поэтому использование fprintf для него создало конфликт, который, по-видимому, был обработан fprintf() и вернул -1 . (как упоминалось в комментариях, возвращаемые значения в случае ошибки могут быть любым отрицательным числом ).
    • В этом смысле условие (i == EOF) вернуло значение true, равное 1. что объясняет ответ.
  2. Вопрос 2 :
    • stderr является выходным потоком, что означает, что печать в него прошла успешно
    • i = ... , i содержит количество записанных символов. >0
    • i == EOF вычисляется равным 0.
    • напечатано 0
  3. Вопрос 3 :
    • fprintf пытается выполнить печать в поток с адресом f
    • f является указателем с мусорным значением, что означает, что он может указывать на память, принадлежащую ОС.
    • Запись на этот адрес привела к сбою компиляции или выполнения
  4. Q4 :
    • fprintf выполняет свою работу и записывает 5 символов в файл f
    • i инициализируется значением 5
    • i != EOF вычисляется 5 != -1 , что является истинным, сохраняется как число 1 в памяти
    • напечатанное значение равно 1

Комментарии:

1. это отличная информация и полностью отвечает на мой вопрос. Спасибо