2012-05-20 13 views
10

Po napotkaniu przez strumień stdio błędu (ale nie EOF), wskaźnik błędu strumienia zostanie ustawiony tak, aby ferror() zwrócił wartość niezerową. Zawsze zakładałem, że więcej informacji jest dostępnych w errno. Ale skąd mam to wiedzieć?Czy stdio zawsze ustawia errno?

Dokumentacja niektórych funkcji [np. man fopen pod Linuksem] mówi, że zostanie również ustawiona errno. Jednak man fgets w ogóle nie wspomina o errno. Glibc stron z informacją są pocieszające:

Oprócz ustawiania wskaźnika błędu związanego ze strumieniem funkcje, które działają na strumieniach również zestaw `errno” w sam sposób, jak odpowiadających im funkcji niskopoziomowych działają na deskryptorze pliku .

Ale nie mam pojęcia, jak silna jest ta gwarancja. Czy jest to wymagane przez standard C? Co dzieje się w Visual C/C++?

Odpowiedz

5

Sam standard C nie wymaga dużej ilości funkcji errno WRT do stdio; określa ferror() ale mówi tylko o tym, że

7.13.10.3 Funkcja ferror Funkcja ferror sprawdza znacznik błędu dla strumienia wskazywanego przez stream. Funkcja ferror zwraca wartość niezerową wtedy i tylko wtedy, gdy dla strumienia ustawiono wskaźnik błędu.

z C99 Draft: http://www.vmunix.com/~gabor/c/draft.html. Wszelkie rzeczywiste kody błędów są, w większości przypadków, definiowane przez implementację.

Jednak biblioteka GNU C na linux jest zgodny ze specyfikacją POSIX również:

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

które są o wiele bardziej dobrze zdefiniowaną w tym kontekście. Na przykład, jeśli spojrzeć na stronie fopen:

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

Zobaczysz wiele szczegółowych informacji, w tym specyficznych kodów errno, pod błędów.

I znowu, biblioteka GNU C używana na praktycznie wszystkich normalnych systemach Linux jest zgodna z POSIX, więc możesz liczyć na te informacje;). Te (online) strony podręcznika POSIX są również ogólnie bardziej szczegółowe niż standardowe strony podręcznika systemowego linuksa (czytaj oba).

WRT do operacji na plikach na innych (nie POSIX) platformach, będą miały własne implementacje. Niestety takie rzeczy nie są przezroczyście przenośne w standardowych strumieniach C. C++ mają jednak bardziej znormalizowaną obsługę błędów.

+1

Dzięki. Definicje POSIX są bardzo pomocne. Na przykład, zgodnie z nimi, "fgets" rzeczywiście ustawia errno.Myślę, że najlepszą strategią dla mojego konkretnego przypadku jest napisanie dla POSIX, a następnie naprawienie problemów z systemem Windows, gdy pojawią się. –

3

Zgodnie ze standardem C11, rozdział 7.21 ("stdio.h"), tylko fgetpos, fsetpos i ftell napisz do errno w przypadku wystąpienia błędu.