光说有毛用


C语言通配符匹配

· by admin · Read in about 3 min · (492 Words)


C语言通配符匹配

工作中经常会遇到通配符,windows控制台程序,linux shell,还有web服务器配置路径,Makefile中。

我来分享两个C语言通配符匹配程序和测试程序;我是抱着拿来主义的想法,年纪大了越越懒得动脑子了。


通配符程序中用到的是*和?

*表示任意多个任意字符

?表示单个任意字符

关于通配符的定义引用百度百科的一段话

通配符是一种特殊语句,主要有星号(*)和问号(?),用来模糊搜索文件。当查找文件夹时,可以使用它来代替一个或多个真正字符;当不知道真正字符或者懒得输入完整名字时,常常使用通配符代替一个或多个真正的字符。 实际上用”*Not?paOd”可以对应Notpad\MyNotpad【*可以代表任何文字】;Notpad\Notepad【?仅代表单个字】;Notepad\Notepod【ao代表a与o里二选一】,其余以此类推。

第一个程序是商业友好的license,请放心使用!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

第二个没有明确标明。

 

两个程序是类似的,第一个程序用的是循环,第二个程序用的是递归。

static int wildcmp(const char* wild, const char* pattern)
{
  // Written by Jack Handy - <A href="mailto:[email protected]">[email protected]</A>
  const char *cp = NULL, *mp = NULL;

  while ((*pattern) && (*wild != '*')) 
  {
    if ((*wild != *pattern) && (*wild != '?')) 
    {
      return 0;
    }
    wild++;
    pattern++;
  }

  while (*pattern) 
  {
    if (*wild == '*') 
    {
      if (!*++wild) 
      {
        return 1;
      }
      mp = wild;
      cp = pattern + 1;
    }
    else if ((*wild == *pattern) || (*wild == '?')) 
    {
      wild++;
      pattern++;
    }
    else
    {
      wild = mp;
      pattern = cp++;
    }
  }

  while (*wild == '*') 
  {
    wild++;
  }
  return !*wild;
}


// The main function that checks if two given strings match. The first
// string may contain wildcard characters
static bool match(const char *first,  const char* second)
{
  // If we reach at the end of both strings, we are done
  if (*first == '\0' && *second == '\0')
    return true;

  // Make sure that the characters after '*' are present in second string.
  // This function assumes that the first string will not contain two
  // consecutive '*' 
  if (*first == '*' && *(first + 1) != '\0' && *second == '\0')
    return false;

  // If the first string contains '?', or current characters of both 
  // strings match
  if (*first == '?' || *first == *second)
    return match(first + 1, second + 1);

  // If there is *, then there are two possibilities
  // a) We consider current character of second string
  // b) We ignore current character of second string.
  if (*first == '*')
    return match(first + 1, second) || match(first, second + 1);
  return false;
}

// A function to run test cases
static void test(const char* first, const char* second)
{
  match(first, second) ? puts("Yes") : puts("No");
}

static void test2(const char* first, const char* second)
{
  wildcmp(first, second) ? puts("Yes") : puts("No");
}

int _tmain(int argc, _TCHAR* argv[])
{
  test("g*ks", "geeks"); // Yes
  test("ge?ks*", "geeksforgeeks"); // Yes
  test("g*k", "gee");  // No because 'k' is not in second
  test("*pqrs", "pqrst"); // No because 't' is not in first
  test("abc*bcd", "abcdhghgbcd"); // Yes
  test("abc*c?d", "abcd"); // No because second must have 2 instances of 'c'
  test("*c*d", "abcd"); // Yes
  test("*?c*d", "abcd"); // Yes

  puts("==================================\n");

  test2("g*ks", "geeks"); // Yes
  test2("ge?ks*", "geeksforgeeks"); // Yes
  test2("g*k", "gee");  // No because 'k' is not in second
  test2("*pqrs", "pqrst"); // No because 't' is not in first
  test2("abc*bcd", "abcdhghgbcd"); // Yes
  test2("abc*c?d", "abcd"); // No because second must have 2 instances of 'c'
  test2("*c*d", "abcd"); // Yes
  test2("*?c*d", "abcd"); // Yes

  return 0;
}

测试结果:

test

 

参考链接:

http://www.codeproject.com/Articles/1088/Wildcard-string-compare-globbing

http://www.geeksforgeeks.org/wildcard-character-matching/#

Comments