从向量中删除空元素

3
我试图从std::vector中删除空条目。这里是一个示例代码,但是有些地方出了问题。
#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";      

}

我正在运行一个for循环来查找空元素并将其删除。应该也有STL方法可以使用,但不确定它如何工作。


3
isspace()函数期望一个int类型参数(历史上是这样,但实际上是字符类型),但你提供了一个std::string类型的参数,这是不兼容的。相反,你可以检查(*it == "" || *it == " ")来达到相同的效果。 - Scheff's Cat
3
你的 for 循环只试图从 vector 的开头删除“空”条目。一旦遇到单个非“空”条目,它就会停止。 - Algirdas Preidžius
1
当你认为“有问题”时,你应该思考为什么你认为有问题。它是否编译?是否存在编译错误?如果没有,它是否按照你的预期行为?你期望它如何行为?它实际上是如何行为的? - eerorika
请返回已翻译的文本:https://en.cppreference.com/w/cpp/algorithm/remove https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom - Kenny Ostrom
1
你要找的是 std::remove_if - PaulMcKenzie
1个回答

4

看起来你的意思是以下内容

#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;
}

程序输出为:

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

关于您的代码,它是低效的,因为您尝试分别删除每个找到的元素,并且例如这个循环

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

不能迭代,因为第一个元素不满足条件isspace(*it),而这个条件还是无效的。也就是说,你正在向一个期望接收 char 类型(更确切地说是 int 类型)对象的函数提供了一个 std::string 类型的对象。

如果使用 C 函数 isspace,那么程序可能如下所示。

#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;
}

程序输出与上面显示的相同。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接