C 库宏 - errno

C 标准库 - <errno.h> C 标准库 - <errno.h>

描述

C 库宏 extern int errno 是通过系统调用设置的,在错误事件中的某些库函数表明了什么发生了错误。

errno 是 C 标准库中的一个宏,定义在 <errno.h> 头文件中。它用于指示在程序运行过程中发生的错误。errno 实际上是一个整数变量,用于存储错误代码。库函数在发生错误时,会设置 errno 为适当的错误代码,以便程序可以检查和处理这些错误。

声明

下面是 errno 宏的声明。

extern int errno

参数

  • NA

返回值

  • NA

使用 errno 的步骤

  1. 包含头文件:在使用 errno 之前,需要包含 <errno.h> 头文件。
  2. 调用函数:调用可能会设置 errno 的函数。
  3. 检查 errno:在函数返回表示错误时,检查 errno 以获取错误类型。
  4. 处理错误:根据 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:管道破裂

注意事项

  1. 线程安全:在多线程环境中,errno 通常实现为线程局部存储(Thread-Local Storage, TLS),确保每个线程有独立的 errno 值。
  2. 初始值:在函数调用成功时,errno 通常不会被修改。因此在处理错误前,应确保 errno 被设置为 0。
  3. 跨平台差异:不同操作系统和 C 标准库实现可能会定义额外的错误码。程序应避免依赖特定错误码的数值。

错误处理建议

  1. 检查返回值:在调用可能失败的函数时,始终检查其返回值。
  2. 设置 errno 为 0:在调用函数前,可以将 errno 设定为 0,以便在函数调用后检查 errno 是否被修改。
  3. 使用 strerrorperrorstrerror 函数将 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;
}

在这个示例中,我们检查了具体的 errno 值并做了相应的处理。如果 errnoEACCES(权限被拒绝)或 ENOENT(没有这样的文件或目录),我们打印特定的错误消息;否则,我们打印通用的错误消息。

<errno.h> 提供了一种标准化的方式来报告和处理程序中的错误,使得错误处理代码更为一致和可维护。

C 标准库 - <errno.h> C 标准库 - <errno.h>