Click here to Skip to main content
13,146,739 members (83,020 online)
Click here to Skip to main content


26 bookmarked
Posted 28 Apr 2011

A Simple Wildcard Matching Function

A Simple Wildcard Matching Function
// WildcardMatch.cpp : Defines the entry point for the console application.

#include <windows.h>
#include <stdio.h>
#include <tchar.h>

//	WildcardMatch
//		pszString	- Input string to match
//		pszMatch	- Match mask that may contain wildcards like ? and *
//		A ? sign matches any character, except an empty string.
//		A * sign matches any string inclusive an empty string.
//		Characters are compared caseless.

bool WildcardMatch(const TCHAR *pszString, const TCHAR *pszMatch)
	// We have a special case were string is empty ("") and the mask is "*".
	// We need to handle this too. So we can't test on !*pszString here.
	// The loop breaks when the match string is exhausted.
	while (*pszMatch)
		// Single wildcard character
		if (*pszMatch==_T('?'))
			// Matches any character except empty string
			if (!*pszString)
				return false;

			// OK next
		else if (*pszMatch==_T('*'))
			// Need to do some tricks.

			// 1. The wildcard * is ignored. 
			//    So just an empty string matches. This is done by recursion.
			//	  Because we eat one character from the match string, the
			//	  recursion will stop.
			if (WildcardMatch(pszString,pszMatch+1))
				// we have a match and the * replaces no other character
				return true;

			// 2. Chance we eat the next character and try it again, with a
			//    wildcard * match. This is done by recursion. Because we eat
			//	  one character from the string, the recursion will stop.
			if (*pszString && WildcardMatch(pszString+1,pszMatch))
				return true;

			// Nothing worked with this wildcard.
			return false;
			// Standard compare of 2 chars. Note that *pszSring might be 0
			// here, but than we never get a match on *pszMask that has always
			// a value while inside this loop.
			if (::CharUpper(MAKEINTRESOURCE(MAKELONG(*pszString++,0)))!=::CharUpper(MAKEINTRESOURCE(MAKELONG(*pszMatch++,0))))
				return false;

	// Have a match? Only if both are at the end...
	return !*pszString && !*pszMatch;

// Test function

void Test(const TCHAR *pszDesc, const TCHAR *pszText, const TCHAR *pszMask)
	_tprintf(_T("%-15sWildcardMatch(\"%s\",\"%s\") \treturns %d\n"),pszDesc,pszText,pszMask,WildcardMatch(pszText,pszMask));

int _tmain(int argc, _TCHAR* argv[])
	Test(_T("Empty string 1"),_T(""),_T("*"));
	Test(_T("Empty string 2"),_T(""),_T(""));
	Test(_T("Simple 1"),_T("MyName.doc"),_T("*.DOC"));
	Test(_T("Simple 2"),_T("MyName.docx"),_T("*.DOC"));
	Test(_T("Complex 1"),_T("MyNamName.docx"),_T("My*Name.*x"));
	Test(_T("Complex 2"),_T("MyNamName.docx"),_T("My*Name.*oc"));
	return 0;

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Martin Richter [exMVP C++]
Software Developer (Senior)
Germany Germany
MVP for C++ in Germany from 2000 up to 2015.
Developer since 1979, working with C/C++ since 1982
Started with Windows development in 1990

Love my bicycles (specially my recumbent) and geocaching

You may also be interested in...

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.170915.1 | Last Updated 28 Apr 2011
Article Copyright 2011 by Martin Richter [exMVP C++]
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid