Linux系统程序员的错误处理

来源:互联网 发布:淘宝商城童装毛衣女孩 编辑:程序博客网 时间:2024/06/06 01:33
程序员的错误处理
要把正确的搞定,也要把错误的搞定,还要防止别人有意无意的破坏;
主流的编程语言(除了C语言外)基本都使用异常机制处理错误,C语言中没有异常机制;
C程序员是用返回值代表是否出错,主要有以下4种情况:
    1.如果返回类型是 int(如主函数/随机数等),并且返回值不可能是负数,正常数据会直接返回,用返回-1代表出错(如返回数组下标>=0);
    2.如果返回类型是 int,并且返回值有可能是负数(如返回两个负数中的大者),此时正常数据用指针返回,返回-1代表出错,0代表正确;
    3.如果返回类型是指针,返回 NULL 代表出错,其他代表正常;
    4.如果函数不需要考虑出错问题,用 void 型函数,无返回值;
注意
    以上4种情况只是经验之谈,大多如此;但不是绝对的;
    如有时返回指针不用NULL而用-1表示出错((void*)-1))也是可以的;

一个函数影响外部数据的方式有2种:
    1.用 return 语句返回;
    2.参数中传递指针形式,也可以影响外部数据;

练习
有4个函数
    a返回两个数的最大值,如果这两个数相等,返回错误;
        /* 数据用指针传递,情况2 */
    b返回0-10的随机数,如果随机数为0则函数返回错误;
        /* 可以用-1表示出错,情况1 */
    c传入一个字符串,如果传入的是"error",返回错误;否则返回原来函数的字符串;
        /* 返回指针,情况3; */
    d打印一个传入的字符串;
        /* 不需要返回值,也无须考虑错误,情况4; */

/* * 错误处理演示 */#include <stdio.h>#include <string.h>#include <stdlib.h>#include <time.h>/* 情况1,正常值非负,用-1表示出错 */int ran10() {    srand(time(0)); //设置种子防止伪随机    int ra = rand() % 11;    if (ra == 0) {        return -1;    }    return ra;    //返回-1代表出错,数据正常返回;}/* 情况2,正常值也有负数,返回0表示正常,数据用指针处理传递 */int max(int num1, int num2, int *pi) {    if (num1 == num2) {        return -1;    //相等则返回    }    *pi = (num1 > num2) ? num1 : num2;    return 0;    //0代表没有出错,数据存在*pi中}/* 情况3,返回值是指针类型,返回NULL代表出错,其他值直接带回 */char *iserror(char *str) {    if (!strcmp(str, "error")) {        return NULL; //返回NULL代表错误    }    return str;    //返回指针}/* 情况4,不需要考虑出错问题,用void型函数; */void print(char *str) {    printf("%s\n", str);}int main() {    int num = 0;    int r = max(-1, -2, &num);    if (r == -1) {        printf("error !\n");    } else {        printf("r = %d, max = %d\n", r, num);    }    r = ran10();    if (r == -1) {        printf("ran error \n");    } else {        printf("r = %d\n", ran10());    }    char *s = iserror("ok");    if (s == NULL) {        printf("iserror error !\n");    } else {        printf("%s\n", s);    }    print(s);    return 0;}



C语言用外部的全局变量errno(error number)记录错误信息;
    错误信息包括错误编号(int)和具体信息(字符串);
    每个错误编号都对应一个具体信息;
    errno存储的是错误编号;
函数strerror()/perror()/printf()用于错误信息的显示和转换;
    char *strerror(int errnum)    传入一个编号,返回具体信息(转换函数);
    void perror(const char *s)    不用传入错误编号,直接打印errno对应的信息(会自动换行);
    printf("%m")    直接打印errno对应的信息;
不是所有的函数都使用errno处理错误,比如线程的函数;

注意安装翻译软件星际译王或goldendict
man命令可以查看命令/函数和头文件等的帮助信息;
如果man命令显示的不是英文,可以首先执行,export LANG="en";

在Linux中获取指令的帮助信息
man string.h
    使用空格或Page Down翻页,也可使用上下键滚屏
    在结果中可以使用搜索,n下一个,N上一个
    q退出
man 3 printf    //查看C库函数
    3表示的是man查找帮助的来源,可分为以下8种;
    首先要查看概述,尤其注意其中的头文件和函数原型,参数类型,返回值类型;
    然后查看描述信息,可以简要了解函数的功能;
    最后还要看函数的返回值的意义;
man find
    查找系统命令的帮助信息;
    首先看name,了解命令的基本功能;
    然后看概述,了解命令的使用形式;
    然后再看描述,了解其具体功能;
    然后还要看选项信息,了解各选项的意义;
    如果可能还可以看一些使用范例;
不需要记住帮助信息,只需要明白使用的有价值的信息即可,用的多的自然就会记住常用的;
man man
The standard sections of the manual include
   1   User Commands //用户命令
   2   System Calls        //系统命令
   3   C Library Functions    //C库函数
   4   Devices and Special Files    //设备和特设文件
   5   File Formats and Conventions    //文件格式与转换
   6   Games et. Al.    //游戏等
   7   Miscellanea    //杂集
   8   System Administration tools and Deamons    //系统管理工具

man strerror
errno只有在出错时才会改变值,不出错也不会恢复值;
因此errno只能说明出过什么错,而不能据此判断当前步骤是否出错;
    若判断是否出错要使用函数的返回值;
    确定出错以后再使用errno判断出了什么错
/* * perror()使用示例 */#include <stdio.h>#include <errno.h>#include <string.h>int main() {    FILE *file = fopen("/etc/passwd1", "r");    if (file == NULL) {    //判断是否出错        printf("[%d] %s\n", errno, strerror(errno));        perror("fopen 出错了");        //perror()会打印"参数: 错误信息"自动换行        //其中参数就是传给perror()的参数;        //函数出错基本都是使用perror(),线程一般不用perror()        printf("%m\n");    } else {        fclose(file);    }    file = NULL;    //如果确保file不再使用可以省略;    return 0;}



0 0
原创粉丝点击