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)
使用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)
归档时间: |
|
查看次数: |
15199 次 |
最近记录: |