• 学习优秀源码 Orisun 博客园


    学习优秀源码 - Orisun - 博客园

    学习优秀源码

    根据文件名的后缀,判断是不是图片

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    char *Pic_list[]={"jpg","bmp","png",NULL};
    int isPic(char *name)
    {
        char **listwalk;
        int len;
     
        for (listwalk = Pic_list; *listwalk; listwalk++) {
            len = strlen(*listwalk);
            if (strlen(name) > len &&
                !strcasecmp(name + strlen(name) - len, *listwalk))
                break;
        }
     
        return (*listwalk != NULL);
    }

    有两点:1.学习在不知道数组长度的情况下如何遍历数组,不是for(i=0;i<arr.len;i++)的形式了,而是创建一个二维数组的迭代器(listwalk=Pic_list)。另外又为什么要单独创建一个char **listwalk=Pic_list,通过listwalk来遍历,而不是直接通过Pic_list来遍历?因为经过几轮的Pic_list++后,Pic_list已不再指向二维数组头部了。

    2.故意设置数组最后一个元素为NULL。因为不知道数组长度,所以我们必须设个数组结束的标志。C语言可不检查数组下标溢出,所以通常情况下溢出的指针指向的不一定是NULL。

    创建多级目录

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    int mkpath(char *path, mode_t mode, mode_t dir_mode)
    {
        struct stat sb;
        register char *slash;   //slash斜线
        int done = 0;
     
        path = slash = strdup(path);
        if (path == NULL) {
            warn("strdup");     /*void warn(const char *fmt, ...);warn()也是根据全局变量errno来查找errmessage,但比perror好在它支持格式化输出*/
            return (-1);
        }
     
        while (!done) {
            slash += strspn(slash, "/");
            slash += strcspn(slash, "/");
     
            done = (*slash == '\0');
            *slash = '\0';
     
            if (stat(path, &sb)) {
                if (errno != ENOENT || (mkdir(path, done ? mode : dir_mode) && errno != EEXIST)) {
                    warn("%s", path);
                    goto err;
                }
            } else if (!S_ISDIR(sb.st_mode)) {      //S_ISDIR判断一个路径是否为目录,在sys/stat.h中还定义了更多相关的函数
                warnx("%s: %s", path, strerror(ENOTDIR));
                goto err;
            }
     
            *slash = '/';
        }
     
        free(path);
        return (0);
     
     err:
        free(path);
        return (-1);
    }

    1.这次同样是使用了两个char*,slash和path来指向路径字符串,path不动始终指向字符串首部,slash则充当迭代器。slash跳过第一个'/',以后遇到一个'/'就把变成'\0',相当于把path截断。这样就可以逐级创建目录了。

    2.看这一行:if (errno != ENOENT || (mkdir(path, done ? mode : dir_mode) && errno != EEXIST)),相当于3行:

    if(errno == ENOENT){

    if(mkdir(path, done ? mode : dir_mode)){

    if(errno != EEXIST){}

           }

    }

    写在一行里是一种更精炼的表达方式。

    大量使用宏定义,除了可以节省代码量外,用宏定义函数可以避免入栈,提高执行效率,这一点跟C++中的inline函数差不多。在C++中是不提倡使用宏定义的,能避免则避免。

  • 相关阅读:
    相关系数的元分析,以及带调节变量的相关系数的元分析(R)
    共有地址网段类别的划分,几个特殊的私有地址,关于子网掩码,网关的小知识 (网络)
    在文件内夹内部建立子文件夹(python)(os)
    晶振, 机器周期,进位 (单片机)
    数码管动态显示,显示从1到9,每一位显示一个数字 (单片机)
    比较R平方的差值,比较两个回归方程的(R)
    react项目控制台报错data.slice.is not function
    useRef源码
    useReducer源码实现
    useContext源码解读
  • 原文地址:https://www.cnblogs.com/lexus/p/2951960.html
Copyright © 2020-2023  润新知