C/C++ 错误处理机制与常用函数
在 C/C++ 编程中,错误信息的捕获和处理是保证程序健壮性的重要部分。错误通常通过函数的返回值或者全局变量 errno 来表示。为了方便调试和错误处理,C/C++ 提供了多种函数和方法来获取和输出错误信息。
1. errno 和 perror()
errno: 是一个全局变量,当系统调用或库函数失败时,它会被设置为一个错误代码。 是由操作系统在发生错误时设置的,每个错误代码代表特定类型的错误。
C/C++ 编程中错误信息的捕获和处理是保证程序健壮性的重要部分。文章介绍了 errno 全局变量、perror 和 strerror 函数的使用方法及区别,以及 exit、abort、assert、setjmp 和 longjmp 等错误控制机制。通过合理运用这些函数,开发者可以有效捕获并报告程序中的错误,帮助在调试和生产环境中定位问题。文中还列举了常见的错误码如 ENOMEM、EINVAL 等及其适用场景。

在 C/C++ 编程中,错误信息的捕获和处理是保证程序健壮性的重要部分。错误通常通过函数的返回值或者全局变量 errno 来表示。为了方便调试和错误处理,C/C++ 提供了多种函数和方法来获取和输出错误信息。
errno: 是一个全局变量,当系统调用或库函数失败时,它会被设置为一个错误代码。 是由操作系统在发生错误时设置的,每个错误代码代表特定类型的错误。errnoerrnoperror():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 设置的错误信息,具体是'没有这样的文件或目录'。
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
perror() 会自动将错误信息输出到标准错误流 stderr,并可以附带自定义的前缀。strerror() 返回一个指向错误信息的指针,可以在程序中自己控制输出。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;
}
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;
}
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;
}
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;
}
perror():适用于错误发生时立即输出错误信息,通常与文件操作、系统调用等直接相关的错误。strerror():适用于在多个地方需要引用或自定义错误消息输出的场景,尤其在日志记录和调试时很有用。ENOMEM:内存不足EAGAIN:暂时不可用,通常表示资源忙或阻塞EINVAL:无效参数EBADF:无效的文件描述符EIO:输入/输出错误EPERM:操作不允许ENOENT:没有文件或目录fopen()、open():文件打开错误,返回 NULL 或 -1,需要使用 errno 判断具体错误。socket():创建套接字时的错误。connect()、send()、recv():网络编程中的错误。C/C++ 提供了一系列强大的错误处理机制,包括全局变量 errno 和函数 perror()、strerror() 等来输出和捕获错误信息。通过合理地使用这些函数,可以有效地捕获并报告程序中的错误,帮助开发人员在调试和生产环境中定位问题。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
暂无推荐文章,稍后可再来查看。
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online