いつperror(“…”)とfprintf(stderr、“…”)を使用する必要がありますか?


105

manページを読むと、いくつかのコードは本当に違いを理解する上で私を助けていなかった-私が使用する必要があるとき、良くも- perror("...")またはfprintf(stderr, "...")

回答:


113

呼び出すperrorと、解釈されたの値が得られますerrno。これは、POSIX syscallsによって書き込まれたスレッドローカルエラー値です(つまり、すべてのスレッドがの独自の値を持っていますerrno)。たとえば、を呼び出しopen()、エラーが生成された(つまり、が返された-1)場合、その後perrorすぐに呼び出して、実際のエラーを確認できます。その間に他のsyscall errnoを呼び出すperrorと、inの値が上書きされ、以前のsyscallによってエラーが生成された場合、その呼び出しは問題の診断に役立ちません。

fprintf(stderr, ...)一方、独自のカスタムエラーメッセージを出力するために使用できます。にstderr出力することで、エラー報告の出力が、「通常の」出力と混ざらないようにすることができますstdout

の呼び出しはの出力文字列値を生成するのとfprintf(stderr, "%s\n", strerror(errno))同様であり、を介して他のカスタムエラーメッセージと組み合わせることができます。perror(NULL)strerror(errno)errnofprintf


3
perr関数は、errnoの値に応じて動作が異なります。If you use a function that effects errno then it makes sense to use perror.errnoに影響を与えず、単にエラーコードを返す関数を使用する場合は、fprintf(stderr、fmt、...)を使用する必要があります。たとえば、文字列が範囲外の場合、strtolはLONG​​_MAXまたはLONG​​_MINを返し、errnoをERANGEに設定します。したがって、範囲外のためにstrtolが失敗した場合は、perrorを使用します。
freeboy1015 2012

6
1つの詳細は、strerrorスレッドセーフである必要はありません。それは愚かですが、それは標準です。strerror_l代わりに、POSIX 2008システムのドロップイン置換として使用できます。strerror_r古いシステムでも利用できますが、一部のシステムでは非準拠バージョンが存在するため、非常に厄介な問題があります。
R .. GitHub ICEのヘルプ停止2012

nitpickとしても、最後にperror追加さ'\n'れると思うので、フォーマットはになり"%s\n"ますか?
Jens Gustedt、2012

1
@R ..、ハ、私はすでに持っています、そして私が知る限り、彼らは私に何かを払っていません。そして、MSはCへのサポートを完全に削減しているようですので、結局私は1人だけになるでしょう:) strerror_sは、実際にはインターフェースとしてはそれほど悪くありません。
Jens Gustedt、2012

2
サポートを完全に切断しますか?彼らは再び委員会をだますようです。彼らの_sジャンクを標準に取り入れることは、基本的にはMSによるゲームでした(「私たちのインターフェースを採用する場合、実際に私たちの製品があなたの標準をサポートするようにすることを検討します。」)そしてもちろん、今は彼らがフォローしていません。実際、私はこの1つのインターフェース自体は悪くないことに同意します。悪いのは、ほとんどの標準ライブラリが「安全でない」こと、および標準ライブラリの_s代わりに関数のファミリ全体を使用する必要があるという(コンパイラ警告の形式の)宣伝です。
R .. GitHub ICE HELPING ICE STOP 2012

40

彼らはかなり違うことをします。

に対応するperror()メッセージを印刷するために使用します。を使用して、やその他のストリームに何かを印刷します。非常に特殊な印刷機能です:stderrerrnofprintf()stderrperror()

perror(str);

に相当

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

12

perror(const char *s):指定した文字列の後に、の現在の値を説明する文字列を出力しますerrno

stderr:これは、独自のエラーメッセージをパイプするために使用される出力ストリームです(デフォルトはターミナルです)。

関連:

char *strerror(int errnum):エラー番号を指定すると、関連するエラー文字列が返されます。


2

perror()は常にstderrに書き込みます。strerr()は、fprintf()と一緒に使用すると、stderrを含め、すべての出力に書き込めます。

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

さらに、perrorは独自のテキスト形式「テキスト:エラーの説明」を課します


-2

Perror関数は、実行呼び出しを実行するのにより多くの時間を要します。ユーザー空間からカーネル空間に移動します。fprintf呼び出しはAPIからカーネルに移動します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.