2012-05-20 2 views
10

Когда поток stdio обнаруживает ошибку (но не EOF), индикатор ошибки потока будет установлен так, что ferror() вернет ненулевое значение. Я всегда предполагал, что больше информации доступно в errno. Но откуда я это знаю?Действительно ли stdio всегда задает errno?

Документация для некоторых функций [. man fopen под Linux] говорит, что errno также будет установлен. Однако man fgets не упоминает errno. В Glibc информационные страницы обнадеживают:

В дополнение к установке индикатора ошибки, связанной с потока, функции, которые работают на потоках, также установленных `ERRNO» в точно так же, как и соответствующие функции низкого уровня, работают с файлами дескрипторы.

Но я не знаю, насколько сильна эта гарантия. Требуется ли это по стандарту C? Что происходит в Visual C/C++?

ответ

5

Сам стандарт C не требует особого использования errno WRT до stdio функций; она определяет ferror(), но говорит об этом только что

7.13.10.3 Функция FERROR Функция FERROR проверяет индикатор ошибки для потока, на который указывает поток. Функция ferror возвращает ненулевое значение тогда и только тогда, когда индикатор ошибки установлен для потока.

от C99 Черновик: http://www.vmunix.com/~gabor/c/draft.html. Любые фактические коды ошибок используются, по большей части, для реализации.

Однако библиотека GNU C на Linux также соответствует спецификациям POSIX:

http://pubs.opengroup.org/onlinepubs/9699919799/toc.htm

которые гораздо более четко определены в данном контексте. Например, если вы смотрите на странице fopen:

http://pubs.opengroup.org/onlinepubs/9699919799/functions/fopen.html

Вы увидите много подробной информации, включая конкретные коды Errno, под Ошибки.

Опять же, библиотека GNU C, используемая практически во всех нормальных Linux-системах, совместима с POSIX, поэтому вы можете рассчитывать на эту информацию;). Те (онлайн) страницы руководства POSIX также, как правило, более детализированы, чем стандартные справочные страницы системы Linux (читайте оба).

WRT для работы с файлами на других (не POSIX) платформах, они будут иметь свои собственные реализации. К сожалению, такие вещи не прозрачно переносятся в стандартном C. С ++ потоки имеют более стандартизованную обработку ошибок.

+1

Спасибо. Определения POSIX очень полезны. Например, в соответствии с ними «fgets» действительно устанавливает errno.Я думаю, что лучшая стратегия для моего конкретного случая - просто написать для POSIX, а затем исправить проблемы с Windows по мере их появления. –

3

В соответствии со стандартом C11, глава 7.21 ("stdio.h"), только fgetpos, fsetpos и ftell запись в errno в случае возникновения ошибки.

Смежные вопросы