C/C++错误信息

devtools/2025/3/29 22:36:26/

目录

1. errno 和 perror()

示例:

2. strerror()

示例:

3. perror() 和 strerror() 区别

4. exit() 和 abort()

示例:

示例:

5. assert()

示例:

6. setjmp() 和 longjmp()

示例:

7. strerror_r()

示例:

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

常见的 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 programreturn 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 errorreturn 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() 等来输出和捕获错误信息。通过合理地使用这些函数,可以有效地捕获并报告程序中的错误,帮助开发人员在调试和生产环境中定位问题。


http://www.ppmy.cn/devtools/169082.html

相关文章

14:00面试,15:00就出来了,问的问题过于变态了。。。

从小厂出来&#xff0c;没想到在另一家公司又寄了。 到这家公司开始上班&#xff0c;加班是每天必不可少的&#xff0c;看在钱给的比较多的份上&#xff0c;就不太计较了。没想到3月一纸通知&#xff0c;所有人不准加班&#xff0c;加班费不仅没有了&#xff0c;薪资还要降40%…

【论文笔记】Transformer

Transformer 2017 年&#xff0c;谷歌团队提出 Transformer 结构&#xff0c;Transformer 首先应用在自然语言处理领域中的机器翻译任务上&#xff0c;Transformer 结构完全构建于注意力机制&#xff0c;完全丢弃递归和卷积的结构&#xff0c;这使得 Transformer 结构效率更高…

element-ui progress 组件源码分享

progress 进度条组件源码分享&#xff0c;主要从以下两个方面&#xff1a; 1、progress 组件页面结构。 2、progress 组件属性。 一、组件页面结构。 二、组件属性。 2.1 percentage 百分比&#xff08;必填&#xff09;&#xff0c;类型为 number&#xff0c;可选值 0-100…

嵌入式开发--Keil MDK仿真时System Viewer不显示寄存器选项--第2篇

缺少SFR文件 在用Keil开发时&#xff0c;特别是很久之前的工程&#xff0c;如果开发环境发生变化&#xff0c;就有可能出现调试时不显示寄存器的问题&#xff0c;初步解决可以看这一篇&#xff1a;嵌入式开发–Keil MDK仿真时System Viewer不显示寄存器选项&#xff0c;但有时…

Redis + 布隆过滤器解决缓存穿透问题

Redis 布隆过滤器解决缓存穿透问题 1. Redis 布隆过滤器解决缓存穿透问题 &#x1f4cc; 什么是缓存穿透&#xff1f; 缓存穿透指的是查询的数据既不在缓存&#xff0c;也不在数据库&#xff0c;导致每次查询都直接访问数据库&#xff0c;增加数据库压力。 例如&#xff1…

Node.js系列(1)--架构设计指南

Node.js架构设计指南 &#x1f3d7;️ 引言 Node.js作为一个高性能的JavaScript运行时环境&#xff0c;其架构设计对于构建可扩展的服务端应用至关重要。本文将深入探讨Node.js的架构设计原则、最佳实践和实现方案。 架构概述 Node.js架构主要包括以下方面&#xff1a; 事…

SpringBoot整合MQTT最详细版(亲测有效)

一、导入pom.xml依赖 <!--mqtt依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-integration</artifactId></dependency><dependency><groupId>org.springframework.in…

Git 分支使用规范全解(多人协作开发适用)

🚀 Git 分支使用规范全解(多人协作开发适用) 本文将为你梳理一套清晰、标准、适合企业/团队使用的 Git 分支管理策略,适用于前后端、边缘端、AI项目等多种场景。 🧩 为什么要规范分支管理? 防止多人协作混乱、冲突频发清晰区分:开发中 / 待发布 / 已上线 的版本快速定…