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

JGr*_*rey 11 c++ string vector

我正在尝试制作一个处理INI文件的小程序,以便在以后的项目中使用,首先通过在加载到内存后减小其大小.从而,

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

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

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

1.    
2. property
3. property
4. 
5. property
Run Code Online (Sandbox Code Playgroud)

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

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

(抱歉不使用迭代器.)

In *_*ico 11

这个:

vLine[i].erase(); 
Run Code Online (Sandbox Code Playgroud)

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

你可能想要的是这样的:

vLine.erase(vLine.begin() + i);
Run Code Online (Sandbox Code Playgroud)

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

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

但是有更简单的方法:使用标准算法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());
Run Code Online (Sandbox Code Playgroud)

如果您可以使用C++ 11编译器,那么您还可以使用lambda表达式更简洁.


Man*_*rse 10

问题出在你删除元素的逻辑上.当您遇到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());
Run Code Online (Sandbox Code Playgroud)


pmr*_*pmr 5

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

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