Все функции буферизованной обработки данных устроены таким образом, что при достижении конца потока или ошибках ввода-вывода они устанавливают соответствующие битовые флаги состояния в структуре управления потоком. Это предоставляет возможность контролировать состояние потока в любой момент, пока он открыт для чтения или записи. Для контроля состояния потока предусмотрены три функции: feof, ferror и clearerr. Они реализованы как макросы в заголовочном файле <stdio.h> системы программирования C. Каждая из этих функций-макросов маскирует соответствующие битовые флаги в структуре управления потоком.
Функция feof применяется для контроля достижения конца потока ввода. Спецификация формата ее вызова имеет вид:
int feof(FILE* stream);
Функция feof проверяет индикатор конца потока в структуре управления, которую адресует указатель stream. Этот индикатор устанавливается, если достигнут конец потока. Функция feof возвращает целочисленное ненулевое значение, когда установлен индикатор конца потока. В противном случае, ее код возврата равен нулю.
Функция ferror применяется для контроля состояния ошибки ввода-вывода. Спецификация формата ее вызова имеет вид:
int ferror(FILE* stream);
Функция ferror проверяет индикатор ошибки ввода-вывода в структуре управления потоком, которую адресует указатель stream. Этот индикатор устанавливается при ошибке ввода-вывода. Функция ferror всегда будет возвращать целочисленное ненулевое значение, пока установлен индикатор ошибки. В противном случае, ее код возврата равен нулю.
Функции feof и ferror следует использовать, если необходимо отличить конец потока от ошибки ввода-вывода, когда эти ситуации неразличимы по коду возврата контролируемой библиотечной функции чтения или записи. Например, функция getc возвращает значение EOF в конце потока ввода, также как при ошибке чтения данных. Чтобы одназначно классифицировать состояние потока в этом случае, достаточно вызвать функцию ferror или feof и проверить их код возврата.
Более общий способ контроля ошибок ввода-вывода предоставляет анализ значения внешней целочисленной переменной errno, которая сохраняет код последней ошибки, необязательно ввода-вывода. Коды ошибок индексируют системный массив диагностических сообщений, который адресует указатель sys_errlist. Для отображения диагностики ошибок может быть использована функция perror. Спецификация формата ее вызова имеет вид:
void perror(conts char* diag);
Функция perror отображает диагностическое сообщение по текущей ошибке через стандартный поток stderr после информационной строки, адресуемой указателем diag. Информационную и диагностическую части вывода функции perror разделяют двоеточие и пробел. Отображение диагностики ошибки автоматически завершает символ перевода строки.
Следующий фрагмент исходного кода демонстрирует применение функции perror для диагностики ошибки, при аварийном завершении функции fopen:
FILE* stream;
if((stream = fopen("any.txt","r")) == NULL) {
  perror("any.txt");
  ..................
} /* if */
Если файл any.txt, специфицированный при вызове функции fopen, не существует, то данный исходный код обеспечит вывод следующего сообщения:
any.txt: No such file or directory
При этом системная переменная errno примет значение 2.
В некоторых случаях перед обращением к функциям чтения-записи полезно проинициализировать флаги состояния в структуре управления потоком, используя функцию clearerr. Спецификация формата ее вызова имеет вид:
void clearerr(FILE* stream);
Функция clearerr принудительно сбрасывает индикаторы конца потока и ошибки ввода-вывода для потока, адресуемого указателем stream. При этом гарантируется, что последующие вызовы функций feof и ferror вернут код, равный нулю, независимо от предыстории обработки потока.