Reputation: 846
I have a string that looks like this:
"{{2,3},{10,1},9}"
and I want to convert it to an array (or vector) of strings:
["{", "{", "2", "}", ",", "{", "10", ",", "1", "}", ",", "9", "}"]
I can't just pull out each character separately because some of the integers may be double-digit, and I can't figure out how to use stringstream because there are multiple delimiters on the integers (could be followed by , or })
Upvotes: 0
Views: 80
Reputation: 846
Thank you Sam and Barry for answering! I actually came up with my own solution (sometimes posting a question here helps me see things more clearly) but yours are much more elegant and delimiter-independent, I'll study them further!
std::vector<std::string> myVector;
std::string nextSubStr;
for (int i=0; i<myString.size(); i++)
{
nextSubStr = myString[i];
// if we pulled a single-digit integer out of myString
if (nextSubStr != "{" && nextSubStr != "}" && nextSubStr != ",")
{
// let's make sure we get the whole integer!
int j=i;
peekNext = myString[++j];
while (peekNext != "{" && peekNext != "}" && peekNext != ",")
{
// another digit on the integer
nextSubStr += peekNext;
peekNext = myString[++j];
i++;
}
}
myVector.push_back(nextSubStr);
}
Upvotes: -1
Reputation: 118292
The logic is straightforward:
Iterate over the string.
push_back()
each character as a string of its own into the output vector, unless it's a digit and the last character was a digit, in which case append the digit to the last string in the output vector:
That's it.
std::string s="{{2,3},{10,1},9}";
std::vector<std::string> v;
bool last_character_was_a_digit=false;
for (auto c:s)
{
if ( c >= '0' && c <= '9')
{
if (last_character_was_a_digit)
{
v.back().push_back(c);
continue;
}
last_character_was_a_digit=true;
}
else
{
last_character_was_a_digit=false;
}
v.push_back(std::string(&c, 1));
}
Upvotes: 0
Reputation: 302718
Just walk through the string. If we're on a digit, walk 'til we're not on a digit:
std::vector<std::string> split(std::string const& s)
{
std::vector<std::string> results;
std::locale loc{};
for (auto it = s.begin(); it != s.end(); )
{
if (std::isdigit(*it, loc)) {
auto next = std::find_if(it+1, s.end(), [&](char c){
return !std::isdigit(c, loc);
});
results.emplace_back(it, next);
it = next;
}
else {
results.emplace_back(1, *it);
++it;
}
}
return results;
}
Upvotes: 3