A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://stackoverflow.com/questions/23457305/compare-strings-with-wildcard below:

c - Compare strings with wildcard

I also liked the code but it does not pass some of my unit tests. So here is my improvement. Like Gurce said it might not be perfect but it is improved.

int is_match(const char* line, const char* pattern)
{
    // returns 1 (true) if there is a match
    // returns 0 if the pattern is not whitin the line
    int wildcard = 0;

    const char* last_pattern_start = 0;
    const char* last_line_start = 0;
    do
    {
        if (*pattern == *line)
        {
            if(wildcard == 1)
                last_line_start = line + 1;

            line++;
            pattern++;
            wildcard = 0;
        }
        else if (*pattern == '?')
        {
            if(*(line) == '\0') // the line is ended but char was expected
                return 0;
            if(wildcard == 1)
                last_line_start = line + 1;
            line++;
            pattern++;
            wildcard = 0;
        }
        else if (*pattern == '*')
        {
            if (*(pattern+1) == '\0')
            {
                return 1;
            }

            last_pattern_start = pattern;
            //last_line_start = line + 1;
            wildcard = 1;

            pattern++;
        }
        else if (wildcard)
        {
            if (*line == *pattern)
            {
                wildcard = 0;
                line++;
                pattern++;
                last_line_start = line + 1 ;
            }
            else
            {
                line++;
            }
        }
        else
        {
            if ((*pattern) == '\0' && (*line) == '\0')  // end of mask
                return 1; // if the line also ends here then the pattern match
            else
            {
                if (last_pattern_start != 0) // try to restart the mask on the rest
                {
                    pattern = last_pattern_start;
                    line = last_line_start;
                    last_line_start = 0;
                }
                else
                {
                    return 0;
                }
            }
        }

    } while (*line);



    if (*pattern == '\0')

    {
        return 1;
    }
    else
    {
        return 0;
    }
}

Here is the test cases it does however pass:

TEST_CASE("is_match") {

    REQUIRE( is_match("abcdefg", "abcdefg")           == 1);
    REQUIRE( is_match("abcdefg", "aacdefg")           == 0);
    REQUIRE( is_match("abcdefg", "*cde*")             == 1);
    REQUIRE( is_match("abcdefg", "cde*")              == 0);
    REQUIRE( is_match("abcdefg", "*cde")              == 0);
    REQUIRE( is_match("abcdfcdefg", "**cde")          == 0);
    REQUIRE( is_match("abcdfcdefg", "**cde*")         == 1);
    REQUIRE( is_match("abcdexxxcdefg", "*cdef*cdef")  == 0);
    REQUIRE( is_match("abcxxdexxxcdefg", "*xxx*?g")   == 1);
    REQUIRE( is_match("abcdexxxcdefg", "*cdef*cdef*") == 0);
    REQUIRE( is_match("abcdefg", "*cdf*cdef*")        == 0);
    REQUIRE( is_match("abcdefg", "*")                 == 1);
    REQUIRE( is_match("", "*")                        == 1);
    REQUIRE( is_match("d", "?")                       == 1);
    CHECK  ( is_match("ddd", "*?")                    == 1);
    CHECK  ( is_match("ddd", "?*")                    == 1);
    CHECK  ( is_match("ddd", "???")                   == 1);
    CHECK  ( is_match("ddd", "*?*")                   == 1);
    CHECK  ( is_match("", "?")                        == 0);
    REQUIRE( is_match("abcdefg", "*?cde*")            == 1);
    REQUIRE( is_match("abcdefg", "??cde??")           == 1);
    REQUIRE( is_match("abcdefg", "??cde?")            == 0);
    REQUIRE( is_match("abcdefg", "ppppp")             == 0);
    REQUIRE( is_match("abcdefg", "??c??")             == 0);
    REQUIRE( is_match("abcdefxxxcdefg", "*cdef*cdef?") == 1);
    REQUIRE( is_match("abcdefxxxcdefg", "*cdef*cdef*") == 1);
    REQUIRE( is_match("abcdefxxxcdefg", "*cdef*cdef") == 0);
}

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4