Home > Enterprise >  C regex - How can I convert std::smatch's elements to e.g. string, size_t and float?
C regex - How can I convert std::smatch's elements to e.g. string, size_t and float?

Time:01-10

I'm quite novice to C , but here's my question. While building a regex to store names and corresponding numbers, I got an error while trying to convert the captured values in my std::smatch object to other types, like a std::string, size_t or float. The values below, given by res [1/2/3/4] do give me what I want when simply outputted through cout. Doing anything more with them doesn't work though. For example, passing them to a function which expects a string or a float.

I tried to figure out the type with e.g. typeid() and see if I could convert it, but no success. The attempt with typeid() gave the following type, which I don't recognize:

NSt7__cxx119sub_matchIN9__gnu_cxx17__normal_iteratorIPKcNS_12basic_stringIcSt11char_traitsIcESaIcEEEEEEE

Here is the relevant code:

#include <regex>
#include <fstream>
#include <string>
#include <typeinfo>
using namespace std;

void regexExampleFunction(string filename)
{
    ifstream file(fileName);
    regex rex("^([A-z.] \\s?[a-z] )\\s([A-z] )\\s(\\d{5})\\s(\\d.\\d)");
    smatch res;                             
    string line;                                      

    while (getline(file, line))          
    {
        regex_search(line, res, rex);
       
        cout << res[1] << " " << res[2] << " " << res[3] << " " << res[4] << '\n';
        cout << typeid(res[1]).name() << '\n'; // outputs the type above^
    }
}

int main(int argc, char **argv)
{
    regexExampleFunction(argv[1]);
}

There must be some error I'm making, or just something I'm missing. It'd be great to hear your feedback.

CodePudding user response:

Mistake you are making:

It looks like you are trying to use the elements of the std::smatch object as if they were of a certain type, but they are actually of type std::sub_match, which is a helper class that represents a sequence of characters within a string.

To use the captured values as a different type, you will need to convert them first. You can use the std::sub_match::str method to get the string representation of the matched sub-expression, and then use one of the standard C type conversion functions such as std::stoi, std::stoul, and std::stof to convert the string to the desired type.

Here's my approach:

To convert the elements of an std::smatch object to different types, you can use standard C type conversion functions such as std::stoi, std::stoul, and std::stof.

For example, to convert the first element of an std::smatch object to a std::string, you can use the std::string constructor that takes an std::string_view object as an argument:

std::string str = std::string(m[1]);

To convert the second element of an std::smatch object to a size_t, you can use the std::stoul function:

size_t num = std::stoul(m[2]);

And to convert the third element of an std::smatch object to a float, you can use the std::stof function:

float f = std::stof(m[3]);

You can also use the std::smatch::str method to get the string representation of an element, and then use one of the above methods to convert it to the desired type.

std::string str = m[1].str();
size_t num = std::stoul(m[2].str());
float f = std::stof(m[3].str());

Hope it clarifies your confusion.

  • Related