Arsen Zahray
Arsen Zahray

Reputation: 25297

Why does the last character double when I erase other characters, and how do I prevent it?

I've got following code:

auto rrr="my mixed string"s;
rrr.erase(std::remove_if(std::begin(rrr), std::end(rrr), [](char const c) { return c == 'm'; }));
std::cout<<rrr<<std::endl;

The output is y ixed stringg

I expected for the code to just remove every m in the string, instead it also added a g at the end

Why did this happen, and how do I fix this?

Upvotes: 2

Views: 44

Answers (2)

Sam Varshavchik
Sam Varshavchik

Reputation: 118340

You're using the wrong erase() overload. You're calling the erase() overload that takes a single iterator parameter, an iterator to the single character to be removed from the string.

std::remove_if "removes" the values from the sequence by simply moving them to the end, and then returns a new "sequence ending" iterator value. Your call to the wrong erase() overload removes only the character after the new sequence. If nothing was removed, you would have passed end() to erase() resulting in undefined behavior and a likely crash. But in this case, you got off lucky.

To completely erase the "removed" characters that were moved to the end of the string, pass the string's end() iterator to erase() as well:

rrr.erase( /* What you already have */, rrr.end());

Your C++ book, or C++ reference manual, should have a complete list of all available overloads of erase(), including the one that you should've used here, and an explanation on what they do.

Upvotes: 5

rafauu
rafauu

Reputation: 101

Or use boost version (if boost is available for you), avoiding all bloaty code.

boost::range::remove_erase_if(rrr, [](char c) { return c == 'm'; });

Upvotes: 1

Related Questions