ewr3243
ewr3243

Reputation: 441

Deleting empty elements from vector

I am trying to delete empty entries from std::vector. Here is a sample code, but something is wrong here.

#include <iostream>
#include <string>
#include<vector>
#include <cctype>

int main()
{
    std::vector<std::string> s1 = {"a"," ", "", "b","c","   ","d"};
    for (auto it = s1.begin(); it != s1.end() && isspace(*it); )
{
        it = s1.erase(it);
}

    std::cout<<"vector size = "<<s1.size();
    for (auto &i:s1) 
        std::cout<<i<<"\n";      

}

I am running a for loop to find out empty elements and deleting from there. There should be STL method too, but not sure how it will work.

Upvotes: 3

Views: 1439

Answers (1)

Vlad from Moscow
Vlad from Moscow

Reputation: 310950

It seems you mean the following

#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>

int main() 
{
    std::vector<std::string> v = { "a", " ", "", "b", "c", "   ", "d" };

    auto is_empty = []( const std::string &s )
    {
        return s.find_first_not_of( " \t" ) == std::string::npos;
    };

    v.erase( std::remove_if( std::begin( v ), std::end( v ), is_empty ), std::end( v ) );

    for ( const auto &s : v )
    {
        std::cout << "\"" << s << "\" ";
    }
    std::cout << std::endl;

    return 0;
}

The program output is

"a" "b" "c" "d" 

As for your code then it is inefficient because you are trying to remove each found element separately and this loop for example

for (auto it = s1.begin(); it != s1.end() && isspace(*it); )
{
    it = s1.erase(it);
}

can iterate never because the first element is not satisfies the condition isspace(*it) that moreover is invalid. That is you are supplying an object of the type std::string to a function that expects an object of the type char (more precisely of the type int).

If to use the C function isspace then the program can look the following way.

#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
#include <cctype>

int main() 
{
    std::vector<std::string> v = { "a", " ", "", "b", "c", "   ", "d" };

    auto is_empty = []( const std::string &s )
    {
        return std::all_of( std::begin( s ), std::end( s ), 
                            []( char c ) 
                            { 
                                return std::isspace( ( unsigned char )c );
                            } );
    };

    v.erase( std::remove_if( std::begin( v ), std::end( v ), is_empty ), std::end( v ) );

    for ( const auto &s : v )
    {
        std::cout << "\"" << s << "\" ";
    }
    std::cout << std::endl;

    return 0;
}

The program output is the same as shown above.

Upvotes: 4

Related Questions