Ошибка сегментации разделения строки C++
Я разбиваю строку на вектор строк
vector<string> tokens;
stringstream strstm(str);
string item;
while (getline(strstm, item, ' ')) {
tokens.push_back(item);
}
token_idx = 0;
cout << "size = " << tokens.size() << endl;
for (unsigned int i = 0; i < tokens.size(); i++)
{
cout << tokens[i] << "[" << i << "]" << endl;
}
Разделение прошло успешно, а size() и его элементы - это то, что мне нравится. Однако последний токен кажется странным, когда я пытаюсь получить его значение.
string Lexer::consume() {
if (hasValue()) {
token_idx++;
cout << "consumed " << tokens[token_idx-1] << " tokens = " << token_idx -1 << endl;
return tokens[token_idx-1];
}
cout << "didn't consume, token_idx = " << token_idx << endl;
return "null";
}
hasVal это так
bool Lexer::hasValue() {
if ( token_idx < tokens.size()) {
return true;
} else {
return false;
}
}
если у меня есть строка ввода, такая 1 + 2 * 3
ожидаемый результат от моей программы должен быть (+1(*23))
Однако я получаю ошибку сегментации.
size = 5
1[0]
+[1]
2[2]
*[3]
3[4]
consumed 1 tokens = 0
consumed + tokens = 1
consumed 2 tokens = 2
consumed * tokens = 3
consumed 3 tokens = 4
Segmentation fault (core dumped)
Но если я изменю значение проверки, ( token_idx < tokens.size() -1 )
, программа вернется (+1 (*2 null))
size = 5
1[0]
+[1]
2[2]
*[3]
3[4]
consumed 1 tokens = 0
consumed + tokens = 1
consumed 2 tokens = 2
consumed * tokens = 3
didn't consume, token_idx = 4
(+1 (*2 null))
Так что мне интересно, есть ли конец строки после 3, когда я разделяю то, что сделал я, или есть другие факторы, способствующие такому поведению? Я вполне уверен, что я не выйду за пределы вектора.
1 ответ
Я думаю, что настоящий инкриминируемый код, генерирующий ошибку, ей не показан, но, поскольку я могу почувствовать, как вы манипулируете индексом, нет никакой тайны, что вы допустили ошибку при доступе через конец в вашем списке токенов, кроме того, что подверженный ошибкам дизайн, вот и все.
if (hasValue()) { // has value is useless to me
token_idx++; // why incrementing this here ?
cout << "consumed " << tokens[token_idx-1] << " tokens = " << token_idx -1 << endl;
return tokens[token_idx-1];
}
измените это на это:
if ( token_idx < tokens.size() ) {
cout << "consumed " << tokens[token_idx] << " tokens = " << token_idx << endl;
return tokens [ token_idx++ ];
}
Также прочитайте о разборе рекурсивного спуска, это действительно просто, и вы будете намного более информированы о разборе, избегая распространенных ошибок.