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;
}
结果:
Error opening file.
获取更多详细信息
如果您想了解关于出错的更多详细信息,可以使用 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;
}
结果:
Error opening file: No such file or directory
使用 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\n", strerror(errno));
return 1;
}
fclose(f);
return 0;
}
结果:
Error: No such file or directory
常见错误代码
错误常量在 <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.\n");
} else {
printf("Some other file error occurred.\n");
}
return 1;
}
fclose(f);
return 0;
}
结果:
The file was not found.
使用 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.\n");
exit(1);
}
fclose(f);
return 0;
}
结果:
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;
}
结果:
Could not open nothing.txt: No such file or directory
总结
- 许多 C 语言函数在出现问题时返回
NULL - 使用
perror()打印关于错误的消息 - 使用
strerror(errno)将错误消息作为字符串获取 errno存储上次失败操作的错误代码- 您可以将
errno与诸如ENOENT(找不到文件)或ENOMEM(内存不足)等值进行比较 - 如果出现错误,使用
exit()提前停止程序
提示:在文件操作、内存分配和系统调用之后,始终检查错误。忽略错误可能导致意外行为或崩溃。