前言
在错误处理一中,我们解释了C语言三种处理方式中的错误号处理方式,这一篇我们在基于上一篇的基础上加入了strerror函数与perror函数,以及断言处理方式的内容......
perror函数
包含头文件:#include <stdio.h>
函数原型:void perror(const char *s);
作用:打印与当前 errno
值相关联的错误消息到标准错误流(stderr)
格式化显示信息:<const char *s>: <由errno值决定的出错信息> </n>
注意事项:
1、perror 应该在产生错误后立即调用,否则可能会被调用其他函数覆盖
2、perror会输出到stderr(标准错误流)而不是标准输出流
常见使用方式:
#define _CRT_SECURE_NO_WARNINGS //忽略文件操作函数不太安全的问题 #include <stdio.h> int main() { FILE* pFile; pFile = fopen("unexist.ent", "rb"); if (pFile == NULL) perror("The following error occurred"); else fclose(pFile); return 0; }
strerror函数
包含头文件:#include <string.h>
函数原型:char *strerror(int errnum);
作用:将给定的错误码转换为对应的错误消息字符串
注意事项:
1、当以错误码erron为参数调用strerror时,函数会返回一个指向描述该错误码对应的错误信息的字符串的指针
2、strerror函数的参数通常是errno的值,但以任意整数作为参数时strerror都能返回一个字符串
3、strerror与perror函数密切相关,若strerror的参数为errno,那么perror所显示的信息与strerror所返回的信息时一样的
常见使用方式:
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <errno.h> int main() { int err = EACCES; // 假设这里有一个特定的错误码 char errMsg[256]; // 为了安全起见,创建一个足够大的缓冲区 strncpy(errMsg, strerror(err), sizeof(errMsg) - 1); //将strerror返回的内容存放在errMsg数组中,sizeof(errMsg) - 1用于防止数组越界 errMsg[sizeof(errMsg) - 1] = '\0'; // 确保数组以'\0'结尾 printf("Error message: %s\n", errMsg); return 0; }
断言处理方式
函数原型:void assert (int expression);
C89标准中表达式的类型必须是int
C99标准中表达式的类型可以是任意标量类型scalar(浮点数、指针等)
包含头文件:#include <assert.h>
作用:在代码中插入检查点,检查表达式中的内容是否为真,若不为真则中断程序
注意事项:
1、C89规定显示的内容至少包括:谁的断言失败、源文件的名称以及发生断言的行号:
Assertion failed:<断言失败的表达式>, file 文件名, line <问题所在行号>
2、C99规定显示的内容至少包括:谁的断言失败,在哪个函数中,在哪个文件中,行号
Assertion failed:<断言失败的表达式>, function 函数名, file 文件名, line <问题所在行号>
3、不同编译器下assert生成的消息格式不完全相同,但都包含基本的信息
//gcc上给出的错误描述信息如下: a.out: demo.c:109: main: Assertion '0<= i && i < 10' failed.
4、在发布版本中,默认情况下编译器可能会禁用所有由 assert 引起的检查
这是因为assert会引入额外的检查,会增加程序的运行时间,在实际开发时,即使是一个很小的运行时间的增加都是不能接受的,因此一般只会在测试阶段使用assert断言,当测试完成时我们会在#include <assert.h>之前加上#define NDEBUG就可以使assert断言失效
5、不要在assert的表达式中使用副作用的表达式,包括函数调用,一旦断言失效这些表达式将不会执行
//assert断言失效后,malloc就不会执行 assert((p = malloc(n)) != NULL)
6、函数assert是在程序运行期间做诊断工作,从C11开始引入的静态断言_Static_assert可以把检查和诊断工作放在程序编译期间进行
常见使用方式:
//#define NDEBUG #include <stdio.h> #include <assert.h> int divide(int a, int b) { assert(b != 0); // 断言:除数不能为0 return a / b; } int main() { int result = divide(10, 2); printf("Result: %d\n", result); result = divide(8, 0); // 这里会触发断言错误 printf("Result: %d\n", result); return 0; }
~over~