Can I remove elements in the std::string object while iterating over it?
for (auto itr = str.rbegin(), rend = str.rend(); itr != str.rend() && *itr == '0'; ++itr)
{
str.pop_back();
}
No, that's not allowed. Modifying the contents of the string invalidates any iterators, particularly itr
.
To remove trailing characters from a string, consider using find_last_not_of
:
auto ix = str.find_last_not_of('0');
str.resize(ix + 1);
Another option is to use the erase
function, which will return the next iterator in the sequence, thereby avoiding having any invalid iterators.
for (auto itr = str.rbegin(); itr != str.rend() && *itr == '0'; /*nothing*/)
itr = str.erase(itr);
That will erase the last character (as pop_back
would) and safely advance the iterator, so you never actually have an invalid iterator anymore. The caveat is that you cannot you the rend
iterator that you were calculating before, because it would be invalid; however, you weren't actually using it anyway.
You can remove elements as you iterate over the string, but you need to write your loop slightly differently to do it safely. In this case, we only really care about the last character in the string, so we can do something like this:
for (auto itr = str.rbegin();
itr != str.rend() && *itr == '0';
itr=str.rbegin())
{
str.pop_back();
}
Even though itr
may be invalidated when we do pop_back
on the string, we're re-fetching the value of str.rbegin()
every iteration, and that's guaranteed to give a valid reverse iterator every time we call it. What we have left no longer really makes good use of a for
loop though--we might about as well use a while
loop:
while (str.rbegin() != str.rend() && *str.rbegin() == '0')
str.pop_back();
I think I'd rather write it something like:
while (!str.empty() && *str.rbegin() == '0')
str.pop_back();
...or (using a slightly cleaner equivalent of *str.rbegin()
:
while (!str.empty() && str.back() == '0')
str.pop_back();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With