C语言通配符匹配、文件名通配符匹配算法(wildchar.c)

 

DOS/Windows的文件名通配符,比如:*.txt,?.txt。上次介绍了一个正则表达式的方法,这次自已写一

个通配符匹配算法,一个函数就OK了(ANSI C的)。

 

一、算法原理

   *号代表任意字符, ?号代表一个字符

   int WildCharMatch(char *src, char *pattern, int ignore_case)

   算法很朴素:从src, pattern中各找一个字符,如果匹配,移动到下一格。如果有*,移动任意长。

二、C语言实现
#include <ctype.h>

/** Defines and Macros */
#define MATCH      1
#define NOT_MATCH  0

/* 匹配一个字符的宏 */
#define MATCH_CHAR(c1,c2,ignore_case)  ( (c1==c2) || ((ignore_case==1) &&(tolower(c1)==tolower(c2))) )

/*  通配符匹配算法
 *        src      字符串
 *        pattern  含有通配符( * 或 ? 号)的字符串
 *        ignore_case 是否区分大小写,1 表示不区分,  0 表示区分
 *
 *  返回1表示 src 匹配 pattern,返回0表示不匹配
 */
int WildCharMatch(char *src, char *pattern, int ignore_case)
{
        int result;

        while (*src)
          {
                if (*pattern == '*')
                    {   /* 如果 pattern 的当前字符是 '*' */
                     /* 如果后续有多个 '*', 跳过 */
                        while ((*pattern == '*') || (*pattern == '?'))
                              pattern++;
                             
                        /* 如果 '*" 后没有字符了,则正确匹配 */
                        if (!*pattern) return MATCH;

                        /* 在 src 中查找一个与 pattern中'*"后的一个字符相同的字符*/
                        while (*src && (!MATCH_CHAR(*src,*pattern,ignore_case)))
                              src++;
                       
                        /* 如果找不到,则匹配失败 */       
                        if (!*src) return NOT_MATCH;

                        /* 如果找到了,匹配剩下的字符串*/
                        result = WildCharMatch (src, pattern, ignore_case);
                        /* 如果剩下的字符串匹配不上,但src后一个字符等于pattern中'*"后的一个字符 */
                        /* src前进一位,继续匹配 */
                        while ( (!result) && (*(src+1)) && MATCH_CHAR(*(src+1),*pattern,ignore_case) )
                           result = WildCharMatch (++src, pattern, ignore_case);

                        return result;

                    }
                else
                    {
                     /* 如果pattern中当前字符不是 '*' */
                     /* 匹配当前字符*/
                        if ( MATCH_CHAR(*src,*pattern,ignore_case) || ('?' == *pattern))
                          {
                            /* src,pattern分别前进一位,继续匹配 */
                            return WildCharMatch (++src, ++pattern, ignore_case);
                          }
                        else
                          {
                             return NOT_MATCH;
                          }
                    }
            }


       /* 如果src结束了,看pattern有否结束*/      
       if (*pattern) 
         {
            /* pattern没有结束*/         
           if ( (*pattern=='*') && (*(pattern+1)==0) ) /* 如果pattern有最后一位字符且是'*' */
             return MATCH;
           else
             return NOT_MATCH;
         }
       else
         return MATCH;
}

三、用法很简单:

    n = WildCharMatch("Aaa.txt","*.txt",1);    //返回1
    printf("\nresult: %d\n",n);

    n = WildCharMatch("Aaaa","a*a",1);   //返回1,这个看似简单,试了别的算法,不一定行的
    printf("\nresult: %d\n",n);

    n = WildCharMatch("Aaaa","a*a",0);  //返回0
    printf("\nresult: %d\n",n);

    n = WildCharMatch("ABA","a?a",1);  //返回1
    printf("\nresult: %d\n",n);

    n = WildCharMatch("ABAd","a?a",1); //返回0
    printf("\nresult: %d\n",n);


四、小结

好了,软件中就能用了,可移植的ANSI C,请在使用时声明源码来源于JoStudio。

BLOG主页: http://blog.csdn.net/c80486

源码及示例可在我的资源库中下载

 


 

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
在rt-thread中,可以通过使用通配符匹配文件名来搜索文件系统中的文件。具体实现方法如下: 1. 编写一个递归函数,遍历文件系统中的所有文件和目录。 2. 对于每个目录,递归调用该函数,直到找到匹配的文件。 3. 对于每个文件名,通过strcmp函数来比较文件名通配符,查看是否匹配。 4. 在匹配的情况下,记录下该文件的路径,同时继续搜索其他的文件和目录。 5. 最终得到所有匹配的文件路径,返回给调用者。 例如,可以使用以下代码实现通配符匹配: ```c /* 递归搜索文件系统中匹配的文件 */ int find_files(const char *path, const char *pattern, char file_list[][MAX_FILE_NAME_LEN], int *index){ struct dirent *dir; DIR *d = opendir(path); if(d){ while((dir = readdir(d)) != NULL){ /* 获取文件名 */ char filename[MAX_FILE_NAME_LEN]; strcpy(filename, dir->d_name); /* 忽略父目录和当前目录 */ if(strcmp(filename, "..") == 0 || strcmp(filename, ".") == 0) continue; char filepath[MAX_FILE_NAME_LEN]; snprintf(filepath, MAX_FILE_NAME_LEN, "%s/%s", path, filename); if(dir->d_type == DT_DIR){ /* 处理目录 */ find_files(filepath, pattern, file_list, index); }else{ /* 处理文件 */ if(match(pattern, filename)){ snprintf(file_list[*index], MAX_FILE_NAME_LEN, "%s/%s", path, filename); (*index)++; } } } closedir(d); } return 0; } /* 比较文件名通配符是否匹配 */ int match(const char *pattern, const char *filename){ if(!*pattern && !*filename) /* 如果pattern和filename都为空,则匹配 */ return 1; if(*pattern == '*' && *(pattern+1) != '\0' && !*filename) return 0; if(*pattern == '?' || *pattern == *filename) return match(pattern+1, filename+1); if(*pattern == '*') return match(pattern+1, filename) || match(pattern, filename+1); return 0; } ``` 该代码使用了递归方法来遍历文件系统中的所有文件和目录。对于每个文件名通配符,使用strcmp函数来进行比较。如果匹配,则记录下该文件的路径,并继续搜索其他的文件和目录。最终得到所有匹配的文件路径,返回给调用者。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值