APUE-错误处理函数

本文探讨了在C语言编程中如何有效地进行错误处理,主要关注标准库提供的错误处理函数,包括它们的使用方法和常见应用场景。通过学习这些函数,开发者可以更好地管理和报告程序运行时的错误情况。
#include <errno.h> // errno
#include <stdarg.h> // 标准C头文件,可变参数
#include "ourhdir.h" // 自定义的头文件

// static:表示该函数只能在该文件中使用
// va_list的指针类型其实是char *
// 函数声明中使用static,函数实现的函数头中要表里如一
static void err_doit(int, const char *, va_list);

// va_list类型的变量通常起名为:ap, 数组指针?
static void err_doit(int errnoflag, const char *fmt, va_list ap) {
    int errno_save;
    char buf[MAXLINE];

    memset(buf, 0, MAXLINE); // 对自动变量初期化
    // 在使用errno的时候首先将其保存在自动变量中
    // 防止在使用的过程中值发生变化
    errno_save = errno;
    // 将可变参数格式化到buf中
    vsprintf(buf, fmt, ap);
    // 根据传入的标识决定是否将errno信息放在buf里打印出来
    if (errnoflag) {
        // 利用strerror函数将errno转化为可读字符串
        sprintf(buf+strlen(buf), ": %s", strerror(errno_save));
    }

    strcat(buf, "\n"); // 在字符串尾端添加换行符
    // L24可改写,省去L27
    // sprintf(buf + strlen(buf, ": %s\n", strerror(errno_save)));

    // 刷新标准输出缓冲区
    // 该文件中出现的出错处理函数都是都是直接输出到标准出错,为了防止标准出错和标准输出是同一个,即将标准错误重定位到标准输出,在此刷新标准出错。
    // 如果标准输入输出涉及到终端设备,则他们是行缓冲的,否则是全缓冲的
    // 标准错误是无缓冲的
    fflush(stdout);

    fputs(buf, stderr); // 将buf输出到标准出错

    fflush(NULL); // 刷新所有的标准流,前面已经做了关于缓冲的操作,为什么这里要刷新所有的标准流?保留L40,删去L36是否完全合理?
    return;
}


// const表示该参数只读
// 从const切开,const是类型修饰符,类型是char,即*fmt的类型是char。
// *fmt的值不能修改。
// 函数中的可变参数用...表示,宏中的可变参数用args...表示。
// 从代码实现的角度来看...如何实现的?
// 输出所有信息,return退出
void err_ret(const char *fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    err_doit(1, fmt, ap);
    va_end(ap);
    return;
}

// 输出所有的信息,exit退出
void err_sys(const char *fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    err_doit(1, fmt, ap);
    va_end(ap);
    exit(1); // 为什么exit(1)而不是exit(0)?
}

// 输出所有错误的信息,产生core文件
void err_dump(const char *fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    err_doit(1, fmt, ap);
    va_end(ap);
    abort(); // 向自己进程发送SIGABORT信号,产生core文件,然后程序终止
    exit(1); // 该语句不会被执行,为什么知道有些语句不会被执行,还要写?
}

// 仅仅为了输出想要输出的信息,即printf的功能
void err_msg(const char *fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    err_doit(0, fmt, ap);
    va_end(ap);
    return;
}

// 输出信息,然后exit退出
void err_quit(const char *fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    err_doit(0, fmt, ap);
    va_end(ap);
    exit(1);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值