1

I want to parser cpu info in Linux. I wrote such code:

// Returns full data of the file in a string
std::string filedata = readFile("/proc/cpuinfo");

std::cmath results;
// In file that string looks like: 'model name : Intel ...'
std::regex reg("model name: *");
std::regex_search(filedata.c_str(), results, reg);

std::cout << results[0] << " " << results[1] << std::endl;

But it returns empty string. What's wrong?

slaphappy
  • 6,894
  • 3
  • 34
  • 59
Max Frai
  • 61,946
  • 78
  • 197
  • 306
  • Don't you mean `cmatch` ? Can you please post the whole code and the contents of `cpuinfo` ? – slaphappy Aug 08 '12 at 10:01
  • See this thread "Difference between regex_match and regex_search?" (http://stackoverflow.com/questions/11628047/difference-between-regex-match-and-regex-search) – SChepurin Aug 08 '12 at 10:44
  • Want to add that it works in VC++2010 with expression corrected by James Kanze in the answer below. – SChepurin Aug 08 '12 at 10:59

3 Answers3

5

Not all compilers support the full C++11 specification yet. Notably, regex_search does not work in GCC (as of version 4.7.1), but it does in VC++ 2010.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 1
    see also: http://gcc.gnu.org/onlinedocs/gcc-4.7.1/libstdc++/manual/manual/status.html#status.iso.2011 – moooeeeep Aug 08 '12 at 10:35
3

You didn't specify any capture in your expression.

Given the structure of /proc/cpuinfo, I'd probably prefer a line oriented input, using std::getline, rather than trying to do everything at once. So you'ld end up with something like:

std::string line;
while ( std::getline( input, line ) ) {
    static std::regex const procInfo( "model name\\s*: (.*)" );
    std::cmatch results;
    if ( std::regex_match( line, results, procInfo ) ) {
        std::cout << "???" << " " << results[1] << std::endl;
    }
}

It's not clear to me what you wanted as output. Probably, you also have to capture the processor line as well, and output that at the start of the processor info line.

The important things to note are:

  1. You need to accept varying amounts of white space: use "\\s*" for 0 or more, "\\s+" for one or more whitespace characters.

  2. You need to use parentheses to delimit what you want to capture.

(FWIW: I'm actually basing my statements on boost::regex, since I don't have access to std::regex. I think that they're pretty similar, however, and that my statements above apply to both.)

James Kanze
  • 150,581
  • 18
  • 184
  • 329
2

Try std::regex reg("model_name *: *"). In my cpuinfo there are spaces before colon.

Tadeusz Kopec for Ukraine
  • 12,283
  • 6
  • 56
  • 83