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

新手上路,请多包涵

我正在尝试制作一个处理 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 顺序的同时删除这些空元素?

(很抱歉在此不使用迭代器。)

原文由 JGrey 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 617
1 个回答

这个:

 vLine[i].erase();

不会从向量中删除 vLine[i] 。表达式 vLine[i] 返回对索引处元素的引用 i 。 So assuming that vLine is of type std::vector<std::string> , the function call erase() actually calls string::erase() on the element, not 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 表达式来更加简洁。

原文由 In silico 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏