Reputation: 11
Is there a way to split a string into small part and store into vector.
For example:
A string: str = "(a b c) d e f [[g h i]]"
. The output expected is:
(a b c)
d e f
[[g h i]]
Sample code:
vector<string> token;
string str = "(a b c)d e f[[g h i]]";
string bracketS = "()[]";
istringstream ss(str);
string section;
string tok;
while (getline(ss,section)) {
size_t start = 0;
size_t end = section.find_first_of(bracketS);
while (end != string::npos) {
tok = section.substr(start, end - start);
token.push_back(tok);
start = end + 1;
end = section.find_first_of(bracketS, start);
}
}
And output is without the brackets:
a b c
d e f
g h i
Tried to adjust my section.substr(start-1, end - start+2)
Then my output is:
(a b c)
) d e f [
[g h i]
Why the middle vector is wrong.
Also tried do strtok. But the output is the same as the first one.
Is there any other way to do it?
Upvotes: 0
Views: 778
Reputation: 322
This is a possible solution with a stack for parsing and throwing a parsing_error if there are opening brackets missing closing brackets or the closing bracket mismatches the opening one.
#include <iostream>
#include <stack>
#include <string>
#include <vector>
const auto Brackets = { std::make_pair('(', ')'), std::make_pair('[', ']') };
const auto is_opening_bracket = [](const char c) {
return std::find_if(Brackets.begin(), Brackets.end(),
[c](const auto& p) { return p.first == c; } ) != Brackets.end();
};
const auto is_closing_bracket = [](const char c) {
return std::find_if(Brackets.begin(), Brackets.end(),
[c](const auto& p) { return p.second == c; } ) != Brackets.end();
};
const auto get_opening_bracket = [](const char c) {
const auto p = std::find_if(Brackets.begin(), Brackets.end(), [c](const auto& p) { return p.second == c; });
if (p == Brackets.end())
return '0';
return p->first;
};
struct parsing_error {};
int main() {
const std::string str = "(a b c)d e f[[g h i]]";
std::stack<char> brackets;
std::vector<std::string> tokens;
std::string token;
for (const auto c : str) {
if (is_opening_bracket(c)) {
if (!token.empty() && brackets.empty()) {
tokens.push_back(token);
token.clear();
}
brackets.push(c);
token += c;
} else if (is_closing_bracket(c)) {
if (brackets.top() != get_opening_bracket(c))
throw parsing_error();
brackets.pop();
token += c;
if (brackets.empty()) {
tokens.push_back(token);
token.clear();
}
} else {
token += c;
}
}
if (!brackets.empty())
throw parsing_error();
for (const auto& token : tokens)
std::cout << token << '\n';
return 0;
}
Upvotes: 1