UNIXには、errnoを対応する文字列に変換する関数がありますか? EIDRMから「EIDRM」。これらの整数errnoのエラーをチェックするためにデバッグするのは非常に面倒です。
strerror()
が実行する必要があります。 http://linux.die.net/man/3/strerror
参考までに、これらのことを自分で簡単に見つけられるようにしてください。manerrno(または調査している関数)と入力し、manページの一番下を見ると、関連する関数のリストが表示されます。それらのそれぞれをman
する場合(名前に基づいて最初に何を行うかを推測して)、同様の質問に対する答えを見つけることがよくあります。
あなたが持っている問題を正確に解決するちょうど別の解決策ですが、Python Cではなく:
>>> import errno
>>> errno.errorcode[errno.EIDRM]
'EIDRM'
Moreutilsパッケージで配布されるerrnoユーティリティがあります。
そのようなenum
スタイルの名前についてはわかりませんが、デバッグとエラー報告の目的で perror(3)
または strerror(3)
人間が読める形式のエラーコードを返すC関数。詳細については、manページを参照してください。
実際にEIDRMが必要で、そのエラー文字列は必要ない場合:いいえ。ただし、OpenBSDでは
man errno|egrep ' [0-9]+ E[A-Z]+'|sed 's/^ *//'|cut -d' ' -f1,2
「...\n89 EIDM\n ...」のニーステーブルを出力します。このテーブルは、この関数を組み込みたいプログラミング言語のデータ構造にさらに変換できます。
UNIXでこれを行うための標準機能はありません。
しかし、私は最近 the errnoname
library と書きました。これは、まさにこれを行うerrnoname
関数を持っています。
strerror
(またstrerror_r
、strerror_l
、perror
)エラーが何であったかについての「人間に優しい」ヒントを出力しますが、それらの出力は
File exists
for EEXIST
。ただし、ファイルではない場合にエラーが返されることがよくあります)。つまり、表面的にはユーザーフレンドリーですが、
皮肉なことに、これらの関数がすべての状況でエラー文字列としてerrno
シンボリック名を使用することを防止防止することは何もありません。特別なC
ロケールのように、特定のロケールに対してのみ実行した場合。しかし、私が知っているlibcはこれを行いません。
とにかく、私のerrnoname
は、寛容なライセンスである "Zero-Clause BSD License"(0BSD)、またはより正確にはパブリックドメイン相当のライセンスの下でリリースされているため、好きなことを何でもできます。
この回答をスタンドアロンにして、回答文字の制限内に収めるには、以下にerrnoname
関数の2つの省略形を示します。
errnoname
ではどちらも実装されていますが、ここでは読みやすくするためにそれぞれの要点を分離しました。
いくつかのメモ:
これは、2020年1月の開始時点でのLinux、Darwin(Mac OS XおよびiOS X)、FreeBSD、NetBSD、OpenBSD、DragonflyBSD、およびいくつかのクローズドソースUnixのerrno
名のすべてまたはほとんどをカバーしています。
名前がわからないerrno
値を指定すると、nullポインタが返されます。
これは非常に移植可能でシンプルであり、心配するEdgeケースはありません。それはあなたがそれに投げかけることができるほぼすべてのC89以上のコンパイラでコンパイルされます。 (おそらくC++コンパイラーでさえ、言語が分かれるにつれてますます珍しくなっています。)
このバリアントcanは、最適化が十分に高くなっている場合に、最新のコンパイラで非常に効率的なコード(switchステートメントではなく配列ルックアップ)にコンパイルされますが、正確な状況に依存しません。
#include <errno.h>
char const * errnoname(int errno_)
{
switch(errno_)
{
#ifdef E2BIG
case E2BIG: return "E2BIG";
#endif
#ifdef EACCES
case EACCES: return "EACCES";
#endif
/*
repeat for the other 100+ errno names,
don't forget to handle possible duplicates
like EAGAIN and EWOULDBLOCK
*/
}
return 0;
}
これは明らかに効率的であり、配列のルックアップを明示的にし、コンピューターの最適化に依存しないため、非常に確実に効率的なコードにコンパイルされます。
システムが正で、比較的小さく、適度に連続したerrno
値を持っている限り、安全に使用できます。
配列の順序指定されていない指定された初期化子を実装するコンパイラでのみコンパイルできます(これまでのすべてのC++バージョンを除くC99以降)。
#include <errno.h>
char const * errnoname(int errno_)
{
static char const * const names[] =
{
#ifdef E2BIG
[E2BIG] = "E2BIG",
#endif
#ifdef EACCES
[EACCES] = "EACCES",
#endif
/*
repeat for the other 100+ errno names,
don't forget to handle possible duplicates
like EAGAIN and EWOULDBLOCK
*/
};
if(errno_ >= 0 && errno_ < (sizeof(names) / sizeof(*names)))
{
return names[errno_];
}
return 0;
}