Reputation: 405675
I'm trying to parse a simple string in C++. I know the string contains some text with a colon, followed immediately by a space, then a number. I'd like to extract just the number part of the string. I can't just tokenize on the space (using sstream and <<) because the text in front of the colon may or may not have spaces in it.
Some example strings might be:
Total disk space: 9852465
Free disk space: 6243863
Sectors: 4095
I'd like to use the standard library, but if you have another solution you can post that too, since others with the same question might like to see different solutions.
Upvotes: 7
Views: 21137
Reputation: 59553
I'm surprised that no one mentioned regular expressions. They were added as part of TR1 and are included in Boost as well. Here's the 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 looks like a lot more work but you get more out of it IMHO.
Upvotes: 3
Reputation: 506847
Similar to Konrads answer, 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;
}
Upvotes: 3
Reputation: 545508
I can't just tokenize on the space (using sstream and <<) because the text in front of the colon may or may not have spaces in it.
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;
}
Upvotes: 4
Reputation: 347206
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)
}
Upvotes: 14
Reputation: 400156
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: the %*[^:]
says to read in as many possible characters that aren't colons, and the *
suppresses assignment. Then, the integer is read in, after the colon and any intervening white space.
Upvotes: 8
Reputation: 75427
const std::string pattern(": ");
std::string s("Sectors: 4095");
size_t num_start = s.find(pattern) + pattern.size();
Upvotes: 2