How to look for std :: string for substring in C ++?

I am trying to parse a simple string in C ++. I know that a line contains colon text followed by a space immediately followed by a number. I would like to extract only part of the line number. I can't just indicate a space (using sstream and <<), because the text before the colon may or may not contain spaces.

Some lines may be:

Total disk space: 9852465

Free disk space: 6243863

Sectors: 4095

I would like to use the standard library, but if you have another solution, you can post this too, as others with the same question may want to see different solutions.

+7
c ++ string
source share
6 answers
std::string strInput = "Total disk space: 9852465"; std::string strNumber = "0"; size_t iIndex = strInput.rfind(": "); if(iIndex != std::string::npos && strInput.length() >= 2) { strNumber = strInput.substr(iIndex + 2, strInput.length() - iIndex - 2) } 
+14
source share

For completeness, here's a simple solution in C:

 int value; if(sscanf(mystring.c_str(), "%*[^:]:%d", &value) == 1) // parsing succeeded else // parsing failed 

Explanation: %*[^:] says that as many characters as possible that are not colons are read, but * suppresses the assignment. Then an integer is read after the colon and any intermediate space.

+8
source share

I can't just indicate a space (using sstream and <<), because the text before the colon may or may not contain spaces.

Right, but you can use std::getline :

 string not_number; int number; if (not (getline(cin, not_number, ':') and cin >> number)) { cerr << "No number found." << endl; } 
+4
source share

Like Konrads, but using istream::ignore :

 int number; std::streamsize max = std::numeric_limits<std::streamsize>::max(); if (!(std::cin.ignore(max, ':') >> number)) { std::cerr << "No number found." << std::endl; } else { std::cout << "Number found: " << number << std::endl; } 
+3
source share

I am surprised that no one mentioned regular expressions. They were added as part of TR1 and are included in Boost . Here's a solution using regex's

 typedef std::tr1::match_results<std::string::const_iterator> Results; std::tr1::regex re(":[[:space:]]+([[:digit:]]+)", std::tr1::regex::extended); std::string str("Sectors: 4095"); Results res; if (std::tr1::regex_search(str, res, re)) { std::cout << "Number found: " << res[1] << std::endl; } else { std::cerr << "No number found." << std::endl; } 

It seems like a lot more work, but you will get more from him IMHO.

+3
source share
 const std::string pattern(": "); std::string s("Sectors: 4095"); size_t num_start = s.find(pattern) + pattern.size(); 
+2
source share

All Articles