#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
string s = "Haven't got an idea why.";
auto beg = s.begin();
auto end = s.end();
while (beg < end)
{
cout << *beg << '\n';
if (*beg == 'a')
{//whithout if construct it works perfectly
beg = s.erase(beg);
}
++beg;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么如果我从此字符串中删除一个或多个字符,此代码会中断?我认为它与返回迭代器有关,因为擦除操作是在比end迭代器更高的地址创建的,但是我不确定它肯定是不正确的行为.或者是吗?
这段代码有几个问题.
s.end(); 它会在您删除元素时更改.beg < end.惯用的方法是写beg != end.如果您尝试迭代过去end,结果是未定义的,并且字符串库的调试版本可能会故意使您的进程崩溃,因此使用它是没有意义的<.s.erase(beg)可能是s.end(),在这种情况下++beg将带您越过末尾.这是(我认为)正确的版本:
int _tmain(int argc, _TCHAR* argv[])
{
string s = "Haven't got an idea why.";
for (auto beg = s.begin(); beg != s.end();)
{
cout << *beg << '\n';
if (*beg == 'a')
{//whithout if construct it works perfectly
beg = s.erase(beg);
}
else
{
++beg;
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:我建议接受FredOverflow的回答.它比上面更简单,更快捷.
从矢量或字符串逐个擦除元素具有二次复杂性.有更好的线性复杂解决方案:
#include <string>
#include <algorithm>
int main()
{
std::string s = "Haven't got an idea why.";
s.erase(std::remove(s.begin(), s.end(), 'a'), s.end());
std::cout << s << std::endl;
}
Run Code Online (Sandbox Code Playgroud)