C 错误处理
C 语言中的错误处理
错误处理可以帮助您检测并应对程序中的问题,例如无法打开的文件或无法分配的内存,从而避免程序崩溃或出现异常行为。
与某些语言不同,C 没有内置的异常处理(如 try/catch)。相反,C 使用返回值、全局错误代码和辅助函数,例如 perror() 和 strerror()。
使用返回值
在上一章中,您学习了像 fopen() 这样的函数在出错时会返回 NULL。
您可以使用 if 语句检查 NULL 值,以便在程序崩溃之前检测和处理错误。
下面这个例子中,我们尝试打开一个不存在的文件。由于 fopen() 函数执行失败,它返回 NULL,因此我们打印一条错误消息:
示例:fopen() 函数调用失败
#include <stdio.h>
int main() {
FILE *fptr = fopen("nothing.txt", "r");
if (fptr == NULL) {
printf("Error opening file.\n");
return 1;
}
fclose(fptr);
return 0;
}
结果:
打开文件时出错。
获取更多详情
如果您想了解更多错误详情,可以使用 perror() 函数。
它会打印自定义错误消息,并附上上次发生的错误的描述:
示例:perror() 与 fopen() 的结合使用
#include <stdio.h>
int main() {
FILE *f = fopen("nothing.txt", "r");
if (f == NULL) {
perror("Error opening file");
return 1;
}
fclose(f);
return 0;
}
结果:
打开文件时出错:没有该文件或目录
使用 strerror() 和 errno
errno 是一个全局变量,用于存储上次失败操作的错误代码。您可以使用 <errno.h> 来访问它,而 strerror(errno) 会将错误代码转换为可读的消息:
示例:strerror()
#include <stdio.h>
#include <errno.h>
#include <string.h>
int main() {
FILE *f = fopen("nothing.txt", "r");
if (f == NULL) {
printf("Error: %s
", strerror(errno));
return 1;
}
fclose(f);
return 0;
}
结果:
错误:没有该文件或目录
常见错误代码
错误常量定义在 <errno.h> 中。您可以将 errno 与这些常量进行比较,以检测具体问题:
| 错误代码 | 含义 |
|---|---|
ENOENT | 没有该文件或目录 |
EACCES | 权限不足 |
ENOMEM | 内存不足 |
EINVAL | 参数无效 |
示例:ENOENT 的自定义消息
#include <stdio.h>
#include <errno.h>
int main() {
FILE *f = fopen("nothing.txt", "r");
if (f == NULL) {
if (errno == ENOENT) {
printf("The file was not found.
");
} else {
printf("Some other file error occurred.
");
}
return 1;
}
fclose(f);
return 0;
}
结果:
文件未找到。
使用 exit() 停止程序
如果程序发生错误时你想立即停止它,可以使用 `exit()` 函数。 它允许你向操作系统返回一个状态码。
退出码有助于指示程序是成功结束还是出错,例如:
0表示成功- 非零值(例如
1或EXIT_FAILURE)表示错误
示例:使用 exit() 函数处理错误
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *f = fopen("nothing.txt", "r");
if (f == NULL) {
printf("Failed to open file.
");
exit(1);
}
fclose(f);
return 0;
}
Result:
Failed to open file.
常用退出状态码
| 代码 | 含义 |
|---|---|
| 0 | 成功 - 程序正常完成 |
| 1 | 错误 - 程序出错 |
| EXIT_SUCCESS | 与 0 相同(定义于 <stdlib.h>) |
| EXIT_FAILURE | 与非零错误代码相同(同样定义于 <stdlib.h>) |
提示: 您可以使用 EXIT_SUCCESS 和 EXIT_FAILURE 代替数字,使代码更易读。
示例:使用 EXIT_FAILURE 和 EXIT_SUCCESS
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *f = fopen("nothing.txt", "r");
if (f == NULL) {
perror("Could not open nothing.txt");
exit(EXIT_FAILURE); // More readable than exit(1)
}
fclose(f);
return EXIT_SUCCESS;
}
结果:
无法打开 nothing.txt:没有该文件或目录
总结
- 许多 C 函数在出错时会返回
NULL - 使用
perror()打印错误信息 - 使用
strerror(errno)获取错误信息字符串 errno存储上次失败操作的错误代码- 您可以将
errno与ENOENT(文件未找到)或ENOMEM(内存不足)等值进行比较。 - 如果出现错误,请使用
exit()提前停止程序
提示:在进行文件操作、内存分配和系统调用后,务必检查错误。忽略错误可能会导致意外行为或崩溃。

