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

本文深入探讨了C语言中如何根据文件后缀判断是否为图片,以及如何在未知数组长度的情况下遍历数组。同时介绍了如何使用C语言创建多级目录,包括使用迭代器进行路径分割和目录创建的技巧。文章详细解释了数组迭代器的使用、NULL结尾的必要性,以及宏定义在代码精简中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

学习优秀源码 - 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++中是不提倡使用宏定义的,能避免则避免。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值