跳转到内容

C 语言 perror 函数

来自代码酷

模板:Note

perror函数概述[编辑 | 编辑源代码]

perror(print error)是C标准库(<stdlib.h>)中用于输出错误信息的函数。当系统调用或库函数失败时,它会将全局变量errno对应的错误描述打印到标准错误流(stderr),格式为:用户自定义字符串 + 冒号 + 错误描述。其函数原型为:

void perror(const char *s);

工作原理[编辑 | 编辑源代码]

1. errno机制:系统调用/库函数失败时会设置errno(整型全局变量)为特定错误码 2. 错误描述转换perror通过查找错误码对应的描述字符串(如ENOENT → "No such file or directory") 3. 输出格式:若参数s非空,输出格式为"s: 错误描述\n"

flowchart LR A[函数调用失败] --> B[设置errno] B --> C[调用perror] C --> D[输出"s: strerror(errno)"]

基础用法示例[编辑 | 编辑源代码]

以下示例演示文件打开失败时的错误处理:

#include <stdio.h>
#include <errno.h> // 必须包含以使用errno

int main() {
    FILE *fp = fopen("nonexistent.txt", "r");
    if (fp == NULL) {
        perror("文件打开失败"); // 输出:文件打开失败: No such file or directory
        return 1;
    }
    fclose(fp);
    return 0;
}

输出示例(当文件不存在时):

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

进阶应用[编辑 | 编辑源代码]

与strerror对比[编辑 | 编辑源代码]

函数 返回值 输出位置 线程安全
perror void(直接输出) stderr 非线程安全(使用全局errno)
strerror char*(返回字符串) 需手动输出 C11起线程安全

多语言环境支持[编辑 | 编辑源代码]

在本地化环境中,perror输出的描述会根据LC_MESSAGES环境变量变化:

#include <locale.h>
setlocale(LC_ALL, "zh_CN.UTF-8"); // 设置为中文环境

实际案例[编辑 | 编辑源代码]

场景:网络编程中的socket错误处理

#include <sys/socket.h>
#include <netinet/in.h>

int main() {
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("socket创建失败");
        // 典型错误: EACCES(权限不足)、EAFNOSUPPORT(地址族不支持)
        return -1;
    }
    return 0;
}

常见错误[编辑 | 编辑源代码]

1. 未包含errno.h:虽然多数编译器隐式声明errno,但标准要求显式包含 2. 错误覆盖:在调用perror前执行其他可能修改errno的操作

   // 错误示例
   if (fp == NULL) {
       printf("调试信息\n"); // 可能修改errno
       perror("失败");      // 此时可能输出错误描述不准确
   }

数学表示[编辑 | 编辑源代码]

错误描述查找过程可表示为: 解析失败 (未知函数“\begin{cases}”): {\displaystyle \text{perror}(s) = \begin{cases} s + ": " + \text{strerror}(\text{errno}) & \text{if } s \neq \text{NULL} \\ \text{strerror}(\text{errno}) & \text{otherwise} \end{cases} }

最佳实践[编辑 | 编辑源代码]

  • 总是检查可能失败的函数返回值后再调用perror
  • 为调试方便,可在错误信息中加入文件名和行号:
  #define LOG_ERROR(msg) perror(__FILE__ ":" #msg)
  • 生产环境中建议结合日志系统使用

页面模块:Message box/ambox.css没有内容。