ZetCode

C strerror 函数

最后修改:2025 年 4 月 8 日

错误处理在 C 编程中至关重要,而 strerror 是将错误编号转换为人类可读消息的关键函数。本教程将深入探讨 strerror,包括其语法、用法和线程安全替代方案。我们将探讨实际示例,并讨论错误报告的最佳实践。理解 strerror 有助于创建更健壮、更用户友好的应用程序。

什么是 strerror?

strerror 函数将错误编号转换为描述性字符串。它在 string.h 中声明,并接受一个参数:错误编号。该函数返回一个指向描述错误的静态字符串的指针。对于线程安全的代码,请考虑 strerror_r,它将消息存储在用户提供的缓冲区中。始终立即使用返回的字符串或将其复制,以避免覆盖。

strerror 的基本用法

此示例演示了将常见错误编号转换为消息。

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

int main() {
    // Set errno to a common error
    errno = ENOENT;
    
    // Get error message
    char *msg = strerror(errno);
    
    printf("Error %d: %s\n", errno, msg);
    
    return 0;
}

在这里,strerrorENOENT 错误编号转换为描述性字符串。errno.h 头文件提供了标准错误编号。返回的字符串是静态的,可能会被后续调用覆盖。这是在 C 程序中获取错误描述的最简单方法。

将 strerror 与文件操作结合使用

此示例展示了将 strerror 与文件操作结合使用。

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

int main() {
    FILE *fp = fopen("nonexistent.txt", "r");
    
    if (fp == NULL) {
        printf("Failed to open file: %s\n", strerror(errno));
        return 1;
    }
    
    fclose(fp);
    return 0;
}

fopen 失败时,errno 会被设置以指示错误。strerror 将其转换为可读的消息。这种模式在文件操作和系统调用中很常见。始终检查返回值,并使用 errno 获取详细的错误信息。该消息有助于用户了解出了什么问题。

线程安全替代方案:strerror_r

此示例演示了线程安全的 strerror_r 函数。

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

int main() {
    char buf[256];
    
    // Get thread-safe error message
    strerror_r(EPERM, buf, sizeof(buf));
    
    printf("Error %d: %s\n", EPERM, buf);
    
    return 0;
}

strerror_r 将错误消息存储在提供的缓冲区中,使其对多线程程序是安全的。该函数接受错误编号、缓冲区和缓冲区大小。这可以避免 strerror 使用静态缓冲区带来的问题。始终确保缓冲区足够大以容纳完整的错误消息。

列出常见错误消息

此示例显示了几个标准错误编号的消息。

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

int main() {
    int errors[] = {EACCES, EAGAIN, EBADF, EEXIST, EINTR};
    int count = sizeof(errors)/sizeof(errors[0]);
    
    for (int i = 0; i < count; i++) {
        printf("Error %d: %s\n", errors[i], strerror(errors[i]));
    }
    
    return 0;
}

该程序列出了五个常见错误编号的消息。该数组包含 errno.h 中的标准错误代码。这演示了 strerror 如何帮助记录可能的错误条件。请注意,具体的消息可能因系统而异。此技术对于调试和日志记录很有用。

使用 strerror 进行自定义错误处理

此示例展示了一个使用 strerror 的自定义错误处理函数。

custom_error.c
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdarg.h>

void log_error(const char *format, ...) {
    va_list args;
    va_start(args, format);
    
    vfprintf(stderr, format, args);
    fprintf(stderr, ": %s\n", strerror(errno));
    
    va_end(args);
}

int main() {
    FILE *fp = fopen("/root/file.txt", "w");
    
    if (fp == NULL) {
        log_error("Failed to open protected file");
        return 1;
    }
    
    fclose(fp);
    return 0;
}

log_error 函数将自定义消息与系统错误信息结合起来。它使用可变参数来实现灵活的格式化。strerror 追加系统错误描述。这比单独使用任何一部分都能产生更具信息量的错误消息。此类函数在大型应用程序中对于一致的错误报告很有价值。

使用 strerror 的最佳实践

来源

C strerror 文档

本教程探讨了 strerror 函数,从基本用法到高级注意事项。正确的错误处理使程序更可靠、更用户友好。在实现错误报告时,请始终考虑线程安全和消息持久性。

作者

我叫 Jan Bodnar,我是一名敬业的程序员,对编码充满热情。自 2007 年以来,我通过 1,400 多篇文章和 8 本电子书分享我的专业知识。凭借十多年的教学经验,我努力使编程变得易于访问且引人入胜。

列表 C 标准库