2012-08-24 14 views

Odpowiedz

86

Wywołanie perror daje interpretować wartość errno, która jest wartością błędu thread-local zapisywane przez syscalli POSIX (to znaczy każdy wątek ma własną wartość dla errno). Na przykład, jeśli wykonałeś połączenie z open() i został wygenerowany błąd (tj. Zwrócił on -1), możesz natychmiast wywołać perror, aby zobaczyć, jaki był faktyczny błąd. Należy pamiętać, że jeśli w międzyczasie wywołasz inne telefony systemowe, zostanie zapisana wartość w errno, a wywołanie perror nie będzie miało żadnego znaczenia w diagnozowaniu problemu, jeśli błąd został wygenerowany przez wcześniejszą syscall.

fprintf(stderr, ...) z drugiej strony może być używany do drukowania własnych niestandardowych komunikatów o błędach. Drukując na stderr, unikasz mieszania danych wyjściowych z raportowaniem błędów z "normalnym" wyjściem, które powinno być ustawione na stdout.

Należy pamiętać, że fprintf(stderr, "%s\n", strerror(errno)) jest podobna do perror(NULL) ponieważ wezwanie do strerror(errno) będzie generować wartość dla errno wydrukowany ciąg, a następnie można łączyć z każdym innym, że komunikat błędu niestandardowego poprzez fprintf.

+2

oh, mam it.The funkcja perror działa różnie w zależności od wartości errno.'Jeśli używasz funkcji, która działa na errno, wtedy sensowne jest używanie perror. Jeśli używasz funkcji, która nie wpływa na errno i po prostu zwraca kod błędu, powinieneś użyć fprintf (stderr, fmt, ...). Na przykład strtol zwróci LONG_MAX lub LONG_MIN, jeśli ciąg jest poza zakresem i ustawi errno na ERANGE. Więc jeśli strtol zawiedzie z powodu spoza zakresu, użyłbym perror. – freeboy1015

+6

Jeden szczegół, 'strerror' nie musi być bezpieczny dla wątków. To głupie, ale to jest standard. Zamiast tego '' strerror_l' może być zastąpiony w systemach POSIX 2008. 'strerror_r' jest również dostępny w starszych systemach, ale ma naprawdę nieprzyjemne problemy z niektórymi systemami mającymi niezgodne z nim wersje. –

+0

również jako nitpick, myślę, że 'perror' dodaje' '\ n'' na końcu, więc format będzie ""% s \ n "', nie? –

8

perror(const char *s): wyświetla podany ciąg, a następnie ciąg, który opisuje bieżącą wartość errno.

stderr: jest to strumień wyjściowy używany do przesyłania własnych komunikatów o błędach (domyślnie do terminala).

Stosowna:

char *strerror(int errnum): nadać mu numer błędu, a będzie to powrót skojarzony błędzie ciąg.

30

Robią raczej różne rzeczy.

Używasz perror(), aby wydrukować wiadomość do stderr, która odpowiada errno. Używasz fprintf() do drukowania dowolnego elementu do stderr lub dowolnego innego strumienia. perror() to bardzo wyspecjalizowane funkcje drukowania:

perror(str); 

jest równoważna

if (str) 
    fprintf(stderr, "%s: %s\n", str, strerror(errno)); 
else 
    fprintf(stderr, "%s\n", strerror(errno)); 
-2

funkcja perror zająć więcej czasu, aby wykonać wywołanie wykonanie idzie z przestrzeni użytkownika do z ziaren przestrzeni ubezpieczeniowy rozmowy fprintf idziesz do API Kernal

0

perror() zawsze zapisuje na stderr; strerr(), używane razem z fprintf(), może pisać na dowolne wyjście - w tym stderr, ale nie wyłącznie.

fprintf(stdout, "Error: %s", strerror(errno)); 
fprintf(stderr, "Error: %s", strerror(errno)); // which is equivalent to perror("Error") 

Ponadto perror narzuca własne formatowanie tekstu "Tekst: opis błędu"

Powiązane problemy