c++for-loopstdvectorerase-remove-idiom

Possible Logic Error: remove(vector.begin(),vector.end(),val)


I am looking for a way to delete certain lines in a file. I read on Stack Overflow that the best way to do this is to write it into a vector, and then remove the element from the array, and then read the array back into the file. I was doing this, and was attempting to remove the elements of the array by using the remove method.

I found this method here:

Removing Method

But this didn't seem to work, and after compiling their code for myself, I found the theirs didn't work either.

Is there something simple I'm missing? Or is this incorrect. This is their code:

#include<bits/stdc++.h>
using namespace std;

int main(){
    vector<int> v;
    //Insert values 1 to 10
    v.push_back(20);
    v.push_back(10);
    v.push_back(30);
    v.push_back(20);
    v.push_back(40);
    v.push_back(20);
    v.push_back(10);

    vector<int>::iterator new_end;
    new_end = remove(v.begin(), v.end(), 20);

    for(int i=0;i<v.size(); i++){
        cout << v[i] << " ";
    }
    //Prints [10 30 40 10]
    return 0;
}

(For further clarification, 'didn't work' means: it printed 20 10 30 20 40 20 10)


Solution

  • Just change the for loop like

    new_end = remove(v.begin(), v.end(), 20);
    
    for ( auto first = v.begin(); first != new_end; first++){
        cout << *first << " ";
    }
    

    Or you could erase the removed elements like

    v.erase( new_end, v.end() );
    for(int i=0;i<v.size(); i++){
       cout << v[i] << " ";
    }
    

    or

    v.erase( new_end, v.end() );
    for ( const auto &item : v ){
       cout << item << " ";
    }
    

    Or you could combine the call of the standard algorithm std::remove with the member function erase like

    v.erase( remove(v.begin(), v.end(), 20), v.end() );
    

    Pay attention to that if your compiler supports C++ 20 then you can just write

    std::erase( v, 20 );