C errno.h标准库

C语言errno.h标准库详解

C语言 标准库

错误处理机制详解 – 编程小白必读指南

📌 什么是errno.h?

errno.h 是C标准库中用于错误处理的头文件。当调用库函数出错时,系统会设置一个全局变量 errno,通过这个变量可以了解发生了什么错误。

简单理解:就像打电话时如果对方没接,手机会告诉你”对方暂时无法接通”或”对方正在通话中”。errno.h 就是告诉你程序哪里出问题的”错误提示系统”。

🔧 errno是什么?

errno 是一个全局整型变量,用于存储最近发生的错误代码。当一个库函数执行失败时,它会设置 errno 的值,表明发生了什么错误。

重要提示:只有在函数明确指明失败时才会设置 errno!成功执行的函数不会修改 errno。

✅ 如何使用errno?

  1. 调用可能失败的库函数(如 fopen()、malloc() 等)
  2. 检查函数返回值是否表示失败
  3. 如果失败,立即检查 errno 的值
  4. 根据 errno 的值进行错误处理

常见错误宏定义

错误宏 含义 常见场景
EPERM 1 操作不允许(权限不足) 尝试修改只读文件
ENOENT 2 文件或目录不存在 打开不存在的文件
EINTR 4 系统调用被中断 等待用户输入时按下Ctrl+C
EIO 5 输入/输出错误 读取损坏的磁盘
EBADF 9 错误的文件描述符 使用了未打开的文件描述符
EAGAIN 11 资源暂时不可用 非阻塞操作无法立即完成
ENOMEM 12 内存不足 malloc失败
EACCES 13 权限不足 尝试打开无权限的文件
EFAULT 14 错误的地址 传递了无效指针
EEXIST 17 文件已存在 创建已存在的文件
EINVAL 22 无效参数 传递了无效参数给函数
ENOSPC 28 设备无空间 磁盘空间不足

错误处理函数

📝 perror()

打印错误信息到标准错误输出(stderr)

#include <stdio.h>
void perror(const char *s);

参数:s – 自定义的错误消息前缀

示例:perror(“文件打开失败”);

输出:文件打开失败: No such file or directory

📝 strerror()

返回错误代码对应的字符串描述

#include <string.h>
char *strerror(int errnum);

参数:errnum – 错误代码(errno的值)

返回值:错误描述的字符串

示例:printf(“错误: %s”, strerror(errno));

完整代码示例

#include <stdio.h>
#include <errno.h>
#include <string.h>

int main() {
    FILE *fp;
    
    // 尝试打开一个不存在的文件
    fp = fopen("nonexistent.txt", "r");
    
    if (fp == NULL) {
        printf("错误代码: %d\n", errno);
        
        // 使用 perror 打印错误信息
        perror("文件打开失败");
        
        // 使用 strerror 获取错误信息
        printf("错误信息: %s\n", strerror(errno));
        
        // 根据不同错误类型处理
        switch(errno) {
            case ENOENT:
                printf("处理:文件不存在,请检查路径\n");
                break;
            case EACCES:
                printf("处理:权限不足,请检查文件权限\n");
                break;
            default:
                printf("处理:未知错误,代码 %d\n", errno);
        }
        
        return 1;
    }
    
    // 文件操作...
    fclose(fp);
    return 0;
}
示例输出:

错误代码: 2

文件打开失败: No such file or directory

错误信息: No such file or directory

处理:文件不存在,请检查路径

注意事项

⚠️ 陷阱警告

  • 成功执行的函数不会重置errno为0
  • 检查errno前必须确认函数执行失败
  • 库函数调用可能覆盖errno的值
  • 在多线程程序中,errno是线程安全的(每个线程有自己的副本)
  • 程序启动时errno初始值为0

✅ 最佳实践

  • 在调用可能失败函数后立即检查errno
  • 使用perror()或strerror()输出错误信息
  • 处理错误时考虑恢复机制或安全退出
  • 不要假设errno的值,总是检查具体错误
  • 复杂的程序建议自定义错误处理函数

为什么errno是一个宏?

在大多数实现中,errno不是一个真正的全局变量,而是一个宏。这是为了支持多线程环境。每个线程都有自己的errno副本,防止一个线程的错误覆盖另一个线程的错误。

© 2023 C语言标准库学习指南 | 编程小白成长之路

errno.h 是C语言错误处理的基石,掌握它让你的程序更加健壮可靠!

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部