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