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?
remove() is an inbuilt function in C++ STL which is declared in header file. remove() is used to remove any specific value/element from the list container. It takes the value which is passed as a parameter and removes all the elements with that value from the list container.
remove_if() The remove_copy_if() algorithm returns an iterator that points to the end of the resulting range. The remove_copy_if() algorithm is stable, which means that the relative order of the elements that are not removed is the same as their relative order in the original range.
First, you use remove_if/remove to move all elements which don't fit the remove criteria to the front of the range, keeping the relative order of the elements. So after calling remove_if/remove , a single call of erase deletes all remaining elements at the end of the range.
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());
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