欢迎来到徐庆高(Tea)的个人博客网站
磨难很爱我,一度将我连根拔起。从惊慌失措到心力交瘁,我孤身一人,但并不孤独无依。依赖那些依赖我的人,信任那些信任我的人,帮助那些给予我帮助的人。如果我愿意,可以分裂成无数面镜子,让他们看见我,就像看见自己。察言观色和模仿学习是我的领域。像每个深受创伤的人那样,最终,我学会了随遇而安。
当前位置: 日志文章 > 详细内容

C/C++错误信息处理的常见方法及函数

2025年04月07日 C/C++
前言在 c/c++ 编程中,错误信息的捕获和处理是保证程序健壮性的重要部分。错误通常通过函数的返回值或者全局变量errno来表示。为了方便调试和错误处理,c/c++ 提供了多种函数和方法来获取和输出错

前言

在 c/c++ 编程中,错误信息的捕获和处理是保证程序健壮性的重要部分。错误通常通过函数的返回值或者全局变量 errno 来表示。为了方便调试和错误处理,c/c++ 提供了多种函数和方法来获取和输出错误信息。以下是 c/c++ 错误处理的常见方法及函数介绍:

1. errno 和 perror()

  • **errno**:errno 是一个全局变量,当系统调用或库函数失败时,它会被设置为一个错误代码。errno 是由操作系统在发生错误时设置的,每个错误代码代表特定类型的错误。

  • **perror()**:perror() 用于打印基于 errno 错误码的错误信息。它将 errno 的值转换为对应的错误消息并输出。如果提供了自定义的前缀字符串,则会一起输出。

示例:

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

int main() {
    file *file = fopen("non_existent_file.txt", "r");
    if (!file) {
        perror("file opening failed");
    }
    return 0;
}

输出:

file opening failed: no such file or directory

在此例中,perror() 输出了一个由 errno 设置的错误信息,具体是“没有这样的文件或目录”。

2. strerror()

  • **strerror()**:strerror() 函数用于将 errno 错误代码转换为可读的字符串,返回与 errno 对应的错误消息的指针。可以在程序中直接调用它来获取详细的错误描述。

示例:

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

int main() {
    file *file = fopen("non_existent_file.txt", "r");
    if (!file) {
        printf("error: %s\n", strerror(errno));
    }
    return 0;
}

输出:

error: no such file or directory

3. perror() 和 strerror() 区别

  • perror() 会自动将错误信息输出到标准错误流 stderr,并可以附带自定义的前缀。
  • strerror() 返回一个指向错误信息的指针,可以在程序中自己控制输出。

4. exit() 和 abort()

  • **exit()**:exit() 用于退出程序并返回一个指定的状态码。返回的状态码可以用来表示程序的执行状态,通常 0 表示成功,非零值表示错误。

示例:

#include <stdio.h>
#include <stdlib.h>

int main() {
    if (some_error_condition) {
        fprintf(stderr, "an error occurred\n");
        exit(1);  // exit with status 1 (error)
    }
    return 0;
}
  • **abort()**:abort() 用于立即终止程序,通常在程序遇到无法恢复的错误时使用。调用 abort() 后,程序会立即中止,并且返回一个未定义的错误状态。

示例:

#include <stdlib.h>
#include <stdio.h>

int main() {
    if (some_fatal_error) {
        abort();  // immediately terminate the program
    }
    return 0;
}

5. assert()

  • **assert()**:assert() 是用于调试时的一个宏,检查条件表达式是否为真。如果条件不为真,程序会输出错误信息并调用 abort() 终止程序。assert() 主要用于开发和调试阶段,不应该用于生产代码。

示例:

#include <assert.h>
#include <stdio.h>

int main() {
    int x = 5;
    assert(x == 10);  // this will fail and abort the program
    return 0;
}

6. setjmp() 和 longjmp()

  • **setjmp()**:setjmp() 用于设置一个恢复点。如果程序在后续调用 longjmp() 时跳转到该恢复点,setjmp() 会返回一个非零值。
  • **longjmp()**:longjmp() 用于从 setjmp() 所在的地方跳转到程序的某个恢复点。它可以用于错误处理,但一般不推荐作为常规的错误处理机制。

示例:

#include <setjmp.h>
#include <stdio.h>

jmp_buf env;

void error_recovery() {
    printf("error occurred, recovering...\n");
    longjmp(env, 1);  // jump back to setjmp
}

int main() {
    if (setjmp(env) != 0) {
        printf("recovered from error\n");
        return 0;
    }
    error_recovery();  // call this to simulate error
    return 0;
}

7. strerror_r()

  • **strerror_r()**:strerror_r() 是线程安全的 strerror() 版本,它将错误信息写入传入的缓冲区中。由于 strerror() 不是线程安全的(它使用静态缓冲区),所以在多线程程序中推荐使用 strerror_r()

示例:

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

int main() {
    char buf[256];
    errno = enoent;
    strerror_r(errno, buf, sizeof(buf));
    printf("error: %s\n", buf);
    return 0;
}

8. perror() 和 strerror() 适用场景

  • **perror()**:适用于错误发生时立即输出错误信息,通常与文件操作、系统调用等直接相关的错误。
  • **strerror()**:适用于在多个地方需要引用或自定义错误消息输出的场景,尤其在日志记录和调试时很有用。

常见的 c/c++ 错误信息和函数

常见的错误信息

  • **enomem**:内存不足
  • **eagain**:暂时不可用,通常表示资源忙或阻塞
  • **einval**:无效参数
  • **ebadf**:无效的文件描述符
  • **eio**:输入/输出错误
  • **eperm**:操作不允许
  • **enoent**:没有文件或目录

常见的函数

  • **fopen()open()**:文件打开错误,返回 null 或 -1,需要使用 errno 判断具体错误。
  • **socket()**:创建套接字时的错误。
  • **connect()send()recv()**:网络编程中的错误。

总结

c/c++ 提供了一系列强大的错误处理机制,包括全局变量 errno 和函数 perror()strerror() 等来输出和捕获错误信息。通过合理地使用这些函数,可以有效地捕获并报告程序中的错误,帮助开发人员在调试和生产环境中定位问题。

到此这篇关于c/c++错误信息处理的常见方法及函数的文章就介绍到这了,更多相关c/c++错误信息内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!