如何在C中打印errno的符号名称?

我可以使用perror()strerror()来打印属于errno的“人类可读”错误消息,但是如果我还要打印errno的符号名称(例如“ EAGAIN ”)该怎么办?

任何方便的function或宏来做到这一点?

更新:附上我最终编写的代码,基于下面接受的答案及其评论的想法:

 #include  #include  #include  int get_errno_name(char *buf, int buf_size) { // Using the linux-only gawk instead of awk, because of the convenient // match() functionality. For Posix portability, use a different recipe... char cmd[] = "e= && " // errno to be inserted here (max digits = 6) "echo '#include ' | " "gcc -dM -E - | " // optionally, use $CC inead of gcc "gawk \"match(\\$0, /^#[[:space:]]*define[[:space:]]+" "(E[[:alnum:]]+)[[:space:]]+$e($|[^[:alnum:]])/, m) " "{ print m[1] }\""; { // Insert the errno as the "e" shell variable in the command above. int errno_digit_c = snprintf(cmd + 2, 6, "%d", errno); if (errno_digit_c  buf_size) { fprintf(stderr, "Read errno name is larger than the character " "buffer supplied to get_errno_name().\n"); return -1; } } } buf[read_size++] = '\0'; if (pclose(f) == -1) { perror("Failed to pclose() in get_errno_name()"); return -1; } return read_size; } 

没有一种简单的方法可以做到这一点。

您可以创建一个程序 – 我创建了一个程序,可以将其重新打包为库函数 – 从数字转换为名称。 但是生成表格是相当困难的。 我使用Perl脚本运行编译器(GCC或等效的)和选项( -H )来列出包含/usr/include/errno.h包含的头文件,然后扫描这些文件,查找名称( #define加上E后跟一个大写字母或数字),数字和注释。 这适用于Linux,Mac OS X,Solaris,HP-UX,AIX。 这不是特别微不足道的。

请注意,Mac OS X上的errno.h包含一个名称ELAST (为要使用的实现保留的名称),它是最高编号的副本(但是映射在发布之间发生变化;在Mountain Lion中它是105,我相信,但在小牛队中是106。

据我所知,你做不到。 一些整数错误常量无论如何都映射到多个符号名称,例如EAGAIN和EWOULDBLOCK。 显然,您可以在设置errno的命令的手册页上查找它们。

如果您知道您期望的错误,可以使用以下样式编写大型switch/caseif/else块来对抗errno

 if (errno == EAGAIN) fprintf(stderr, "EAGAIN"); 

显而易见的问题是,如果你想要特定的errno’name’,你需要针对每个可能的选项进行编写,而且还有很多。

我不知道有哪个函数可以执行此操作,但如果您熟悉程序中返回的错误,则编写一个函数并不困难。

您可以编写包含strerror()输出的字符串,并使用for循环和if语句使用strcmp()(返回基于成功或失败的值)来比较您编写的字符串。 如果它们相同,则可以输出符号名称*,如果将其设置为另一个字符串。

由于符号名称存储为枚举, C将它们视为Ints 。 您将不得不创建一个类似于此SO问题的函数如何将枚举名称转换为c中的字符串 。 你可以很容易地将它缩短到一个宏,但是必须为每个错误创建一个案例。