0

I have a function which looks like this:

bool ExpandWildCard(vector<string>& names, vector<string>& result, string& wildcard) 
{
}

Here, I want to match the wildcard with each element in the vector names and if it does match, then add the element in names to the result vector.

Of course, if the wildcard is *, I could just add everything from names to results. Also I'm just trying to implement the * wildcard for now.

How can I do this in C++?

One way I thought of doing this was using find() algorithm but I am not sure I would match wildcards using that?

jxh
  • 69,070
  • 8
  • 110
  • 193
user3638992
  • 87
  • 2
  • 9

2 Answers2

1

It looks like you are looking for some combination of std::copy_if and maybe std::regex_match:

bool ExpandWildCard(vector<string>& names, vector<string>& result, string& wildcard) {
  auto oldsize = result.size();
  std::copy_if(std::begin(names), std::end(names),
    std::back_inserter(result),
    [&](string const& name) {
      return std::regex_match(name, make_regex(wildcard));
    }
  );

  return (result.size() > oldsize);
}

Where make_regex would be the function you need to implement to convert your string into a std::regex.

Arne Mertz
  • 24,171
  • 3
  • 51
  • 90
0

The approach you are probably after in using regex_match as suggested in another answer. Elsewhere you can find code to convert a glob pattern into a regular expression.

If performance is not a concern, and you just need the functionality, you can use the shell to match the pattern for you. You can create a suitable command, pass the command through popen() and read the results and store them in your vector.

bool ExpandWildCard (const std::vector<std::string>& names,
                     std::vector<std::string>& result,
                     const std::string& wildcard)
{
    std::ostringstream oss;
    oss << "bash -c 'for word in ";
    for (int i = 0; i < names.size(); ++i) {
        if (names[i].size() > 0) oss << '"' << names[i] << '"' << ' ';
    }
    oss << "; do case \"$word\" in "
        << wildcard << ')' << " echo \"$word\" ;; *) ;; "
        << "esac ; done '";
    FILE *fp = ::popen(oss.str().c_str(), "r");
    if (fp == NULL) return false;
    char *line = 0;
    ssize_t len = 0;
    size_t n = 0;
    while ((len = ::getline(&line, &n, fp)) > 0) {
        if (line[len-1] == '\n') line[len-1] = '\0';
        result.push_back(line);
    }
    ::free(line);
    ::pclose(fp);
    return true;
}
Community
  • 1
  • 1
jxh
  • 69,070
  • 8
  • 110
  • 193