strerror函数如何返回错误信息字符串?

99ANYc3cd6
预计阅读时长 14 分钟
位置: 首页 C语言 正文

什么是 strerror

strerror 是 C 标准库中的一个函数,它的主要作用是将一个错误码(一个整数)转换为一个对应的、可读的错误信息字符串

c语言strerror
(图片来源网络,侵删)

当你调用系统调用或库函数时,如果发生错误,通常会设置一个全局的变量 errno 来表示具体的错误原因。errno 是一个整数值,1 表示 EPERM(操作不允许),2 表示 ENOENT(没有这样的文件或目录)等,这些数字本身对用户来说并不直观,strerror 就是为了解决这个问题而存在的。

strerror 是 C 语言中处理错误信息的“翻译官”。


函数原型

strerror 函数的原型定义在 <string.h> 头文件中:

char *strerror(int errnum);

参数:

c语言strerror
(图片来源网络,侵删)
  • errnum: 你想要查询的错误码,通常就是全局变量 errno 的值。

返回值:

  • 返回一个指向静态分配的字符串的指针,这个字符串描述了 errnum 对应的错误信息。
  • errnum 不是一个已知的错误码,函数通常会返回一个类似 "Unknown error" 的字符串。
  • 重要提示:返回的指针指向的是一个静态内存区域,这意味着:
    • 不应该尝试修改这个字符串。
    • 如果你连续调用 strerror,前一次调用返回的字符串内容可能会被后一次调用覆盖,如果你需要长期保存这个字符串,应该使用 strdup 进行复制,或者自己手动创建一个副本。

使用示例

下面我们通过一个实际的例子来演示 strerror 的用法,我们将尝试打开一个不存在的文件,这会触发错误,然后我们使用 strerror 来打印出具体的错误信息。

示例 1:基本用法

#include <stdio.h>
#include <string.h> // 包含 strerror 函数
#include <errno.h>  // 包含 errno 变量
int main() {
    FILE *fp;
    // 尝试打开一个不存在的文件
    fp = fopen("this_file_does_not_exist.txt", "r");
    // fopen 返回 NULL,说明打开失败
    if (fp == NULL) {
        // 全局变量 errno 被自动设置为相应的错误码
        // 我们使用 perror 函数来打印错误信息,它会自动调用 strerror
        perror("fopen failed"); 
        // perror 打印的内容类似于:fopen failed: No such file or directory
        // 或者,我们可以手动调用 strerror 来获取并打印错误信息
        printf("Error opening file: %s\n", strerror(errno));
    }
    return 0;
}

编译和运行结果:

gcc strerror_example.c -o strerror_example
./strerror_example

输出:

fopen failed: No such file or directory
Error opening file: No such file or directory

在这个例子中,fopen 失败后,errno 被设置为 ENOENT(值为 2)。perror 函数内部就调用了 strerror(errno) 来获取 "No such file or directory" 这个字符串,并将其打印出来,我们手动调用的 strerror(errno) 也得到了同样的结果。


perror 的关系

strerrorperror 是紧密相关的两个函数,它们经常一起出现。

  • *`perror(const char s)`**:

    • 它会打印两条信息到标准错误输出。
    • 第一条信息是你传入的字符串 s,后面跟一个冒号和一个空格。
    • 第二条信息是 strerror(errno) 返回的错误描述字符串,后面跟一个换行符。
    • 作用:快速、方便地打印出带有你自定义前缀的错误信息。
  • strerror(int errnum):

    • 它只做一件事:将错误码 errnum 转换为字符串。
    • 它不负责打印,只负责“翻译”。
    • 作用:提供更灵活的错误处理,比如将错误信息记录到日志文件中,或者进行更复杂的格式化。

对比:

  • perror("fopen"); -> fopen: No such file or directory
  • printf("fopen: %s\n", strerror(errno)); -> fopen: No such file or directory
  • printf("Log: Operation failed with error %d (%s)\n", errno, strerror(errno)); -> Log: Operation failed with error 2 (No such file or directory)

常见错误码与对应信息

下面是一些在 Linux/Unix 系统中常见的 errno 值及其 strerror 返回的字符串:

错误码 (值) 宏定义 错误信息 (strerror 返回) 中文含义
1 EPERM Operation not permitted 操作不允许
2 ENOENT No such file or directory 没有文件或目录
3 ESRCH No such process 没有此进程
4 EINTR Interrupted system call 系统调用被中断
5 EIO I/O error 输入/输出错误
6 ENXIO No such device or address 没有此设备或地址
12 ENOMEM Out of memory 内存不足
13 EACCES Permission denied 权限被拒绝
17 EEXIST File exists 文件已存在
22 EINVAL Invalid argument 无效参数
28 ENOSPC No space left on device 设备上没有剩余空间
32 EPIPE Broken pipe 管道破裂

注意事项

  1. 线程安全:在传统的 C 库中,strerror 返回的静态字符串可能会导致线程安全问题,因为一个线程的调用可能会覆盖另一个线程的结果,为了解决这个问题,POSIX 标准引入了一个线程安全的版本 strerror_r

  2. strerror_r 简介:

    • strerror_r 有两种实现方式(GNU 和 XSI),你需要查阅手册页来确定你的系统使用的是哪一种。

    • 它通常需要一个缓冲区作为参数,将错误信息写入这个缓冲区,而不是返回一个静态指针,从而避免了线程安全问题。

    • 示例:

      #include <string.h>
      #include <errno.h>
      char buf[256];
      strerror_r(errno, buf, sizeof(buf));
      printf("Error: %s\n", buf);
特性 描述
头文件 <string.h>
功能 将错误码转换为可读的错误字符串。
参数 一个整数错误码(通常是 errno)。
返回值 指向静态错误字符串的指针。不要修改它,如果需要长期保存,请复制它。
常见用途 errno 配合使用,通过 perrorprintf 打印友好的错误信息。
线程安全 基础版本不是线程安全的,推荐使用线程安全的 strerror_r

strerror 是 C 语言编程中处理错误反馈不可或缺的工具,掌握它的使用能让你的程序调试和用户体验都得到显著提升。

-- 展开阅读全文 --
头像
dede如何获取当前域名?
« 上一篇 04-18
模型如何调用?
下一篇 » 04-18

相关文章

取消
微信二维码
支付宝二维码

目录[+]