поток — C ++ извлечение строкового значения

Я пытаюсь извлечь значения из myString1 с помощью std::stringstream как показано ниже:

// 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;
}

Выход:

mathOperator: +
value: 50
timeUnit: years

В выводе вы можете видеть, как я успешно извлекаю нужные мне значения, математический оператор, значение и единицу времени.

Есть ли способ сделать то же самое с myString2? Возможно, в цикле? Я могу извлечь математический оператор, значение, но единица времени просто извлекает все остальное, и я не могу придумать, как обойти это. Очень признателен.

2

Решение

Проблема в том, что timeUnit является строкой, поэтому >> будет извлекать что-либо до первого пробела, которого у вас нет в вашей строке.

Альтернативы:

  • Вы можете извлечь части, используя getline (), которая извлекает строки, пока не найдет разделитель. К сожалению, у вас нет одного потенциального разделителя, но 2 (+ и -).
  • Вы можете выбрать использование регулярных выражений непосредственно в строке
  • Вы могли бы наконец разделить строки, используя find_first_of() а также substr(),

В качестве иллюстрации приведем пример с регулярным выражением:

  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]
}

Здесь живое демо применение вашего кода для извлечения всех элементов.

4

Другие решения

Вы могли бы что-то более надежное, как <regex> как в примере ниже:

#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

LIVE DEMO

1

Я бы использовал getline для timeUnit, но с тех пор getline может взять только один разделитель, я бы искать строку отдельно для mathOperator и использовать это:

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);
1
По вопросам рекламы [email protected]