UNIX中是否有任何函数将errno转换为相应的字符串,例如: EIDRM到“EIDRM”。调试以检查这些整数errnos的错误非常烦人。
答案 0 :(得分:69)
strerror()
应该这样做。 http://linux.die.net/man/3/strerror
仅供参考,以便您可以更轻松地找到这些内容:如果您键入man errno(或您正在调查的任何函数),并查看手册页的最底部,您将看到一个列表相关功能。如果你man
中的每一个(根据他们的名字猜测哪一个先做),你会经常找到类似问题的答案。
答案 1 :(得分:10)
另一种解决方案可以解决您遇到的问题,但是在Python中而不是C:
>>> import errno
>>> errno.errorcode[errno.EIDRM]
'EIDRM'
答案 2 :(得分:5)
现在有一个与moreutils包一起发布的errno实用程序。
答案 3 :(得分:4)
我不确定这样的enum
- 样式名称,但是出于调试和错误报告的目的,您可以使用返回人类可读表示的perror(3)
或strerror(3)
C函数。错误代码。有关更多详细信息,请参阅手册页。
答案 4 :(得分:3)
如果你确实想要EIDRM而不是它的错误字符串:no。但是,在OpenBSD上,
man errno|egrep ' [0-9]+ E[A-Z]+'|sed 's/^ *//'|cut -d' ' -f1,2
打印出一个漂亮的“... \ n89 EIDM \ n ...”表格,您可以将其进一步转换为您希望使用此功能的编程语言的数据结构。
答案 5 :(得分:1)
在UNIX中没有标准功能可以做到这一点。
但是我最近写了the errnoname
library,它具有一个errnoname
函数,可以完全做到这一点。
strerror
(还有strerror_r
,strerror_l
,perror
)打印出有关错误原因的“人性化”提示,但其输出是
File exists
打印EEXIST
,即使对于不是文件的错误通常会返回)。这意味着它们表面上对用户友好,但是
具有讽刺意味的是,在所有情况下都不能仅仅通过将errno
符号名称用作其错误字符串来防止这些错误-它将在标准的含义之内,尤其是如果它们仅是针对特定的语言环境(例如特殊的C
语言环境)执行的。但是我不知道有没有libc。
无论如何,由于我的errnoname
是根据“零条款BSD许可证”(0BSD)发行的,该许可证是许可的许可证,或更准确地说是等效于公共域的许可证,因此您可以执行任何操作
为使该答案独立存在,同时仍能满足答案字符的限制,下面是errnoname
函数的两个缩写形式。
在errnoname
中,它们均已实现,但在这里,我将它们的要点分开以使其更具可读性。
笔记夫妇:
截至8月初,这涵盖了Linux,Darwin(Mac OS X和iOS X),FreeBSD,NetBSD,OpenBSD,DragonflyBSD和几个封闭源Unixes的全部或大部分errno
名称2019。
如果您给它提供一个NULL
值(它不知道其名称),它将返回一个errno
指针。
这是一款非常便携和简单的产品,无需担心任何边缘情况。它几乎可以用任何C89或更好的编译器进行编译。 (可能甚至是C ++编译器,随着语言的多样化,这种情况也变得越来越罕见。)此变体不能用现代编译器编译为有效的代码,但应该很好地适合于将来编译器可以轻松实现的优化过程。
#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
值,该函数的性能就会更高,并且仍然可以安全使用。
只能在对数组实现乱序指定初始化程序的编译器上进行编译(C99或更高版本,到目前为止不包括所有C ++版本。)
#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;
}