C 库宏 - errno
描述
C 库宏 extern int errno 是通过系统调用设置的,在错误事件中的某些库函数表明了什么发生了错误。
errno 是 C 标准库中的一个宏,定义在 <errno.h> 头文件中。它用于指示在程序运行过程中发生的错误。errno 实际上是一个整数变量,用于存储错误代码。库函数在发生错误时,会设置 errno 为适当的错误代码,以便程序可以检查和处理这些错误。
声明
下面是 errno 宏的声明。
extern int errno
参数
- NA
返回值
- NA
使用 errno 的步骤
- 包含头文件:在使用
errno之前,需要包含<errno.h>头文件。 - 调用函数:调用可能会设置
errno的函数。 - 检查
errno:在函数返回表示错误时,检查errno以获取错误类型。 - 处理错误:根据
errno的值,采取适当的错误处理措施。
实例
下面的实例演示了 errno 宏的用法。
实例
#include <stdio.h>
#include <errno.h>
#include <string.h>
extern int errno ;
int main ()
{
FILE *fp;
fp = fopen("file.txt", "r");
if( fp == NULL )
{
fprintf(stderr, "Value of errno: %d\n", errno);
fprintf(stderr, "Error opening file: %s\n", strerror(errno));
}
else
{
fclose(fp);
}
return(0);
}
让我们编译并运行上面的程序,当文件 file.txt 不存在时,将产生以下结果:
Value of errno: 2 Error opening file: No such file or directory
常见的 errno 值
EPERM:操作不允许ENOENT:没有这样的文件或目录ESRCH:没有这样的进程EINTR:中断的系统调用EIO:输入/输出错误ENXIO:没有这样的设备或地址E2BIG:参数列表太长ENOMEM:内存不足EACCES:权限被拒绝EFAULT:坏的地址EBUSY:资源忙EEXIST:文件已存在EXDEV:跨设备链接ENODEV:没有这样的设备ENOTDIR:不是一个目录EISDIR:是一个目录EINVAL:无效的参数ENFILE:系统文件表溢出EMFILE:打开的文件过多ENOTTY:不是终端设备ETXTBSY:文本文件忙EFBIG:文件过大ENOSPC:设备上没有空间ESPIPE:非法的寻址EROFS:只读文件系统EMLINK:链接过多EPIPE:管道破裂
注意事项
- 线程安全:在多线程环境中,
errno通常实现为线程局部存储(Thread-Local Storage, TLS),确保每个线程有独立的errno值。 - 初始值:在函数调用成功时,
errno通常不会被修改。因此在处理错误前,应确保errno被设置为 0。 - 跨平台差异:不同操作系统和 C 标准库实现可能会定义额外的错误码。程序应避免依赖特定错误码的数值。
错误处理建议
- 检查返回值:在调用可能失败的函数时,始终检查其返回值。
- 设置
errno为 0:在调用函数前,可以将errno设定为 0,以便在函数调用后检查errno是否被修改。 - 使用
strerror和perror:strerror函数将errno转换为可读的错误消息字符串;perror函数打印出带有描述性错误消息的errno值。
详细的错误处理
下面是一个更详细的示例,演示如何处理不同的 errno 值:
实例
#include <stdio.h>
#include <errno.h>
#include <string.h>
int main() {
FILE *file = fopen("nonexistent_file.txt", "r");
if (file == NULL) {
switch (errno) {
case EACCES:
printf("Error: Permission denied\n");
break;
case ENOENT:
printf("Error: No such file or directory\n");
break;
default:
printf("Error opening file: %s\n", strerror(errno));
}
return 1;
}
// 文件处理代码
fclose(file);
return 0;
}
#include <errno.h>
#include <string.h>
int main() {
FILE *file = fopen("nonexistent_file.txt", "r");
if (file == NULL) {
switch (errno) {
case EACCES:
printf("Error: Permission denied\n");
break;
case ENOENT:
printf("Error: No such file or directory\n");
break;
default:
printf("Error opening file: %s\n", strerror(errno));
}
return 1;
}
// 文件处理代码
fclose(file);
return 0;
}
在这个示例中,我们检查了具体的 errno 值并做了相应的处理。如果 errno 是 EACCES(权限被拒绝)或 ENOENT(没有这样的文件或目录),我们打印特定的错误消息;否则,我们打印通用的错误消息。
<errno.h> 提供了一种标准化的方式来报告和处理程序中的错误,使得错误处理代码更为一致和可维护。
C 标准库 - <errno.h>
Crossing7
126***1330@qq.com
大家可以修改上述代码里 errno 的值从而得出不同的错误类型,从 43 之后就一直是 Unknown error 错误类型。
Crossing7
126***1330@qq.com
duckduck
pan***20812@gmail.com
我做一个补充,上面应该是Windows环境下的输出,linux 下是(CentOS release 6.10 (Final))。
duckduck
pan***20812@gmail.com