Paradox
Paradox

Reputation: 2035

C++ Unexpected behavior with remove_if

I am trying to use std::remove_if to remove spaces from a simple string, but I am getting weird results. Could someone help me figure out what's going on?

The Code is:

#include <iostream>
#include <algorithm>
#include <string>

int main(int argc, char * argv[])
{
    std::string test = "a b";
    std::remove_if(test.begin(), test.end(), isspace);
    std::cout << "test : " << test << std::endl; 

    return 0;
}

I expect this to simply print out:

test : ab

but instead I get

test : abb

Trying with another string, I get:

Input: "a bcde uv xy"

Output: "abcdeuvxy xy"

It seems like it duplicating the last "word", but sometimes adds a space. How can I just get it to remove all spaces without doing weird stuff?

Upvotes: 6

Views: 193

Answers (1)

songyuanyao
songyuanyao

Reputation: 172924

std::remove_if performs removing by shifting elements; the removed elements won't be erased from the container in fact. STL algorithms don't have such privilege; only containers can remove their elements.

(emphasis mine)

Removing is done by shifting (by means of move assignment) the elements in the range in such a way that the elements that are not to be removed appear in the beginning of the range. Relative order of the elements that remain is preserved and the physical size of the container is unchanged. Iterators pointing to an element between the new logical end and the physical end of the range are still dereferenceable, but the elements themselves have unspecified values (as per MoveAssignable post-condition). A call to remove is typically followed by a call to a container's erase method, which erases the unspecified values and reduces the physical size of the container to match its new logical size.

You can erase the removed elements afterward (which is known as erase–remove idiom).

test.erase(std::remove_if(test.begin(), test.end(), isspace), test.end());

Upvotes: 11

Related Questions