Reputation: 3751
I am trying to extract values from myString1
using std::stringstream
like shown below:
// Example program
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main()
{
string myString1 = "+50years";
string myString2 = "+50years-4months+3weeks+5minutes";
stringstream ss (myString1);
char mathOperator;
int value;
string timeUnit;
ss >> mathOperator >> value >> timeUnit;
cout << "mathOperator: " << mathOperator << endl;
cout << "value: " << value << endl;
cout << "timeUnit: " << timeUnit << endl;
}
Output:
mathOperator: +
value: 50
timeUnit: years
In the output you can see me successfully extract the values I need, the math operator, the value and the time unit.
Is there a way to do the same with myString2
? Perhaps in a loop? I can extract the math operator, the value, but the time unit simply extracts everything else, and I cannot think of a way to get around that. Much appreciated.
Upvotes: 2
Views: 12980
Reputation: 73627
The problem is that timeUnit is a string, so >>
will extract anything until the first space, which you haven't in your string.
Alternatives:
find_first_of()
and substr()
.As an illustration, here the example with regex:
regex rg("([\\+-][0-9]+[A-Za-z]+)", regex::extended);
smatch sm;
while (regex_search(myString2, sm, rg)) {
cout <<"Found:"<<sm[0]<<endl;
myString2 = sm.suffix().str();
//... process sstring sm[0]
}
Here a live demo applying your code to extract ALL the elements.
Upvotes: 4
Reputation: 99172
I'd use getline
for the timeUnit
, but since getline
can take only one delimiter, I'd search the string separately for mathOperator
and use that:
string myString2 = "+50years-4months+3weeks+5minutes";
stringstream ss (myString2);
size_t pos=0;
ss >> mathOperator;
do
{
cout << "mathOperator: " << mathOperator << endl;
ss >> value;
cout << "value: " << value << endl;
pos = myString2.find_first_of("+-", pos+1);
mathOperator = myString2[pos];
getline(ss, timeUnit, mathOperator);
cout << "timeUnit: " << timeUnit << endl;
}
while(pos!=string::npos);
Upvotes: 1
Reputation: 42929
You could something more robust like <regex>
like in the example below:
#include <iostream>
#include <regex>
#include <string>
int main () {
std::regex e ("(\\+|\\-)((\\d)+)(years|months|weeks|minutes|seconds)");
std::string str("+50years-4months+3weeks+5minutes");
std::sregex_iterator next(str.begin(), str.end(), e);
std::sregex_iterator end;
while (next != end) {
std::smatch match = *next;
std::cout << "Expression: " << match.str() << "\n";
std::cout << " mathOperator : " << match[1] << std::endl;
std::cout << " value : " << match[2] << std::endl;
std::cout << " timeUnit : " << match[4] << std::endl;
++next;
}
}
Expression: +50years
mathOperator : +
value : 50
timeUnit : years
Expression: -4months
mathOperator : -
value : 4
timeUnit : months
Expression: +3weeks
mathOperator : +
value : 3
timeUnit : weeks
Expression: +5minutes
mathOperator : +
value : 5
timeUnit : minutes
Upvotes: 2