Das Lesen der Manpages und eines Codes hat mir nicht wirklich geholfen, den Unterschied zwischen - oder besser, wann ich es verwenden sollte - perror("...")oder zu verstehen fprintf(stderr, "...").
Das Lesen der Manpages und eines Codes hat mir nicht wirklich geholfen, den Unterschied zwischen - oder besser, wann ich es verwenden sollte - perror("...")oder zu verstehen fprintf(stderr, "...").
Antworten:
Der Aufruf perrorwird Ihnen das interpretiert Wert errno, der einen lokalen Thread-Fehlerwert von POSIX syscalls geschrieben ist (dh jeder Thread für seinen eigenen Wert hat errno). Wenn Sie beispielsweise einen Anruf getätigt open()haben und ein Fehler generiert wurde (dh zurückgegeben wurde -1), können Sie perrorsofort danach anrufen , um den tatsächlichen Fehler zu ermitteln. Beachten Sie, dass beim Aufrufen anderer Systemaufrufe in der Zwischenzeit der Wert in überschrieben errnowird und das Aufrufen perrorbei der Diagnose Ihres Problems nicht hilfreich ist, wenn ein Fehler durch einen früheren Systemaufruf generiert wurde.
fprintf(stderr, ...)Auf der anderen Seite können Sie Ihre eigenen benutzerdefinierten Fehlermeldungen drucken. Durch Drucken auf stderrvermeiden Sie, dass Ihre Fehlerberichtsausgabe mit der "normalen" Ausgabe gemischt wird, die verwendet werden soll stdout.
Beachten Sie, dass dies fprintf(stderr, "%s\n", strerror(errno))ähnlich ist, perror(NULL)da ein Aufruf von strerror(errno)den gedruckten Zeichenfolgenwert für generiert errnound Sie diesen dann mit jeder anderen benutzerdefinierten Fehlermeldung über kombinieren können fprintf.
strerrornicht threadsicher sein. Es ist dumm, aber das ist der Standard. strerror_lkann stattdessen als Drop-In-Ersatz auf POSIX 2008-Systemen verwendet werden. strerror_rist auch auf älteren Systemen verfügbar, hat jedoch bei einigen Systemen mit nicht konformen Versionen wirklich schlimme Probleme.
perrorfügt '\n'am Ende hinzu, so dass das Format wäre "%s\n", nein?
strerror_sist eigentlich keine schlechte Schnittstelle.
_sMüll in den Standard zu bringen, war im Grunde ein Spiel von MS ("Wenn Sie unsere Schnittstellen übernehmen, werden wir in Betracht ziehen, unsere Produkte tatsächlich dazu zu bringen, Ihren Standard zu unterstützen.") Und natürlich folgen sie jetzt nicht mehr. Eigentlich stimme ich zu, dass diese eine Schnittstelle an sich nicht schlecht ist. Was schlecht ist, ist die Propaganda (in Form von Compiler-Warnungen), dass der größte Teil der Standardbibliothek "unsicher" ist und dass die gesamte _sFunktionsfamilie anstelle der Standardfunktionen verwendet werden sollte.
Sie machen ziemlich unterschiedliche Dinge.
Sie verwenden perror(), um eine Nachricht zu drucken, stderrdie entspricht errno. Sie verwenden fprintf()drucken etwas zu stderroder über anderen Strom. perror()ist eine sehr spezielle Druckfunktion:
perror(str);
ist äquivalent zu
if (str)
fprintf(stderr, "%s: %s\n", str, strerror(errno));
else
fprintf(stderr, "%s\n", strerror(errno));
perror(const char *s): Gibt die Zeichenfolge aus, die Sie ihm geben, gefolgt von einer Zeichenfolge, die den aktuellen Wert von beschreibt errno.
stderr: Es ist ein Ausgabestream, an den Sie Ihre eigenen Fehlermeldungen weiterleiten (standardmäßig an das Terminal).
Relevant:
char *strerror(int errnum): Geben Sie eine Fehlernummer ein, und die zugehörige Fehlerzeichenfolge wird zurückgegeben.
perror () schreibt immer in stderr; strerr () kann zusammen mit fprintf () in jede Ausgabe schreiben - einschließlich stderr, aber nicht ausschließlich.
fprintf(stdout, "Error: %s", strerror(errno));
fprintf(stderr, "Error: %s", strerror(errno)); // which is equivalent to perror("Error")
Darüber hinaus legt perror einen eigenen Text fest, der "text: error description" formuliert.
Die Perror-Funktion benötigt mehr Zeit, um einen Ausführungsaufruf auszuführen, der vom Benutzerbereich zum Kernalbereich wechselt, während fprintf-Aufrufe von API zu Kernal gehen
If you use a function that effects errno then it makes sense to use perrorWenn Sie eine Funktion verwenden, die errno nicht beeinflusst und einfach einen Fehlercode zurückgibt, sollten Sie fprintf (stderr, fmt, ...) verwenden. Beispielsweise gibt strtol LONG_MAX oder LONG_MIN zurück, wenn eine Zeichenfolge außerhalb des Bereichs liegt, und setzt errno auf ERANGE. Wenn strtol aufgrund eines Bereichs außerhalb des Bereichs fehlschlägt, würde ich perror verwenden.