C语言错误处理之 “strerror和perror函数以及断言处理方式”

目录

前言

perror函数

strerror函数

断言处理方式


前言

在错误处理一中,我们解释了C语言三种处理方式中的错误号处理方式,这一篇我们在基于上一篇的基础上加入了strerror函数与perror函数,以及断言处理方式的内容......

perror函数

包含头文件:#include

函数原型:void perror(const char *s);

作用:打印与当前 errno 值相关联的错误消息到标准错误流(stderr)

格式化显示信息:: <由errno值决定的出错信息>

注意事项:

1、perror 应该在产生错误后立即调用,否则可能会被调用其他函数覆盖

2、perror会输出到stderr(标准错误流)而不是标准输出流

常见使用方式:

#define _CRT_SECURE_NO_WARNINGS //忽略文件操作函数不太安全的问题
#include 

int main()
{
    FILE* pFile;
    pFile = fopen("unexist.ent", "rb");
    if (pFile == NULL)
        perror("The following error occurred");
    else
        fclose(pFile);
    return 0;
}

C语言错误处理之 “strerror和perror函数以及断言处理方式”_第1张图片

strerror函数

包含头文件:#include

函数原型:char *strerror(int errnum);

作用:将给定的错误码转换为对应的错误消息字符串

注意事项:

1、当以错误码erron为参数调用strerror时,函数会返回一个指向描述该错误码对应的错误信息的字符串的指针

2、strerror函数的参数通常是errno的值,但以任意整数作为参数时strerror都能返回一个字符串

3、strerror与perror函数密切相关,若strerror的参数为errno,那么perror所显示的信息与strerror所返回的信息时一样的

常见使用方式:

#define _CRT_SECURE_NO_WARNINGS 
#include 
#include 
#include 

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;
}

C语言错误处理之 “strerror和perror函数以及断言处理方式”_第2张图片

断言处理方式

函数原型:void assert (int expression); 

C89标准中表达式的类型必须是int

C99标准中表达式的类型可以是任意标量类型scalar(浮点数、指针等)

包含头文件:#include

作用:在代码中插入检查点,检查表达式中的内容是否为真,若不为真则中断程序

注意事项:

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 之前加上#define NDEBUG就可以使assert断言失效

5、不要在assert的表达式中使用副作用的表达式,包括函数调用,一旦断言失效这些表达式将不会执行

//assert断言失效后,malloc就不会执行
assert((p = malloc(n)) != NULL)

6、函数assert是在程序运行期间做诊断工作,从C11开始引入的静态断言_Static_assert可以把检查和诊断工作放在程序编译期间进行 

常见使用方式:

//#define NDEBUG
#include 
#include 

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;
}

C语言错误处理之 “strerror和perror函数以及断言处理方式”_第3张图片

~over~

你可能感兴趣的:(c语言,开发语言)