从字符串向量中删除空元素

时间:2011-10-07 02:19:25

标签: c++ string vector

我正在尝试创建一个处理INI文件的小程序,以便在以后的项目中使用,首先通过在加载到内存后减小其大小。因此,

其中vLine是包含文件内容的向量

for (unsigned int i = 0; i < vLine.size(); i++)
{
   if (!vLine[i].find(';', 0))
   {
       vLine[i].erase();
   }
}

打印vLine后,我会留下空格,一旦有一个以冒号开头的行,例如

1.    
2. property
3. property
4. 
5. property

使用resize()似乎从列表中删除最后一个元素,而不是删除这些空白部分。我存在同样的问题,我删除只包含带有erase()的空格的行。

是否可以在保留vLine的顺序的同时删除这些空元素?

(抱歉不使用迭代器。)

3 个答案:

答案 0 :(得分:10)

此:

vLine[i].erase(); 

不会从矢量中删除vLine[i]。表达式vLine[i]返回对索引i处的元素的引用。因此,假设vLine的类型为std::vector<std::string>,函数调用erase()实际上会调用元素上的string::erase(),而不是向量上的vector::erase()。您所做的只是将该特定元素留空。

你可能想要的是这样的:

vLine.erase(vLine.begin() + i);

这实际上从向量中删除了元素。现在,这确实使向量的所有当前迭代器无效,并且索引将不再正确。在这种情况下,您确实需要使用迭代器。

std::vector<std::string>::iterator i = vLine.begin();
while(i != vLine.end())
{
    if(i->find(';', 0) != std::string::npos)
    {
        i = vLine.erase(i);
    }
    else
    {
        ++i;
    }
}

但是有更简单的方法:使用标准算法std::remove_if()和仿函数,然后调用vLine.erase()

struct HasSemicolon
{
    bool operator()(const std::string& s)
    {
        return s.find(';', 0) != std::string::npos;
    }
};

// ...

vLine.erase(std::remove_if(vLine.begin(), vLine.end(), HasSemicolon()), vLine.end());

如果你可以使用C ++ 11编译器,那么你也可以使用lambda表达式来更简洁。

答案 1 :(得分:8)

问题在于您删除元素的逻辑。当您遇到要删除的索引i处的元素时,会清除其值,但不会将其从矢量中删除。

执行您想要做的事情的标准和简单方法是std::remove_if

vLine.erase(
    std::remove_if(
        vLine.begin(),
        vLine.end(),
        [](std::string const& s) { return s.size() != 0 && s.front() == ';'; }),
    vLine.end());

答案 2 :(得分:5)

使用erase / remove-idiom,最好使用C ++ 11中的lambda:

foo.erase(std::remove_if(foo.begin(), foo.end(), 
                         [](const std::string& s) 
                         { return s.find(';', 0); }));