Проверка stdin и stdout с помощью внешней функции

Влияет ли область видимости на проверку ошибок при получении ввода из стандартного ввода или вывода в стандартный вывод? Например, если у меня есть тело кода, построенное следующим образом:

void streamCheck(){
   if (ferror(stdin)){
      fprintf(stderr, "stdin err");
      exit(1);
   }
   if (ferror(stdout)){
      fprintf(stderr, "stdout err");
      exit(2);
   }
}

int main(){
   int c = getchar();
   streamCheck();
   ...
   putchar(c) 
   streamCheck();
}

На возвращаемые значения ferror(stdin) / ferror(stdout) влияет тот факт, что я проверяю их в функции, а не в основном? Если есть лучший способ сделать это, также дайте мне знать, что я новичок в C.

3 ответа

Пока ты звонишь ferror в конкретном потоке перед вызовом любой другой функции в этом потоке все должно быть в порядке.

Неважно, что ferror вызывается из другой функции, которая getchar или putchar был вызван из.

В вашей функции нет проблем. ferror() проверяет индикатор ошибки FILE *который передается как аргумент. Другими словами, индикатор ошибки является свойством файлового объекта и может быть получен непосредственно изFILE *указатель. Поэтому куда бы вы ни звонилиferror() из, он сможет определить, произошла ли ошибка с FILE * который передается как аргумент (то есть, конечно, если аргумент действителен).

влияет ли на возвращаемые значения ferror(stdin) / ferror(stdout) тот факт, что я проверяю их в функции, а не в основном?

Возвращаемое значение ferror()является характеристикой текущего состояния потока, который вы указываете в качестве аргумента. В любой момент времениstdin предоставленный stdio.h относится к одному и тому же потоку с одинаковым состоянием во всех функциях, включая main(). Следовательно, вы получите тот же результат, вызвавferror() функционируют косвенно, через посредническую функцию, как если бы вы вызывали ее напрямую.

НИКОГДА подход, который вы представляете в своем примере, плох. По большей части функции стандартной библиотеки C показывают, произошла ли ошибка, с помощью их возвращаемых значений. В частности,getchar() возвращает специальное значение, представленное макросом EOF, Если либо конец файла встречается или произошла ошибка. Это типично для функций stdio. Вам следует последовательно тестировать возвращаемые значения функций, чтобы распознавать возникновение исключительных условий. Для потоковых функций вы должны вызватьferror() и / или feof()только после обнаружения такого условия и только в том случае, если вы хотите различать случай конца файла и случай ошибки ввода-вывода (и случай "ни одного" для некоторых функций). См. Также "Почему 'while (! Feof (file))' всегда неверно?"

Лично я, вероятно, не стал бы писать универсальную функцию, такую ​​как ваш streamCheck()вообще, поскольку обработка ошибок обычно зависит от ситуации. Но если бы я его написал, то я бы обязательно протестировал только один поток, который я ему указывал. Примерно так:

void streamCheck(FILE *stream, const char *message, int exit_code) {
   if (ferror(stream)) {
      fputs(message, stderr);
      exit(exit_code);
   }
}

int main(void) {
   int c = getchar();

   if (c == EOF) {
       streamCheck(stdin, "stdin err\n", 1);
   }

   // ...

   if (putchar(c) == EOF) {
       streamCheck("stdout err\n", 2);
   }
}
Другие вопросы по тегам