#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;
}
为什么我从此字符串中删除一个或多个字符,此代码会中断?我认为它与返回迭代器有关,因为擦除操作是在比end迭代器更高的地址创建的,但是我不确定它肯定是不正确的行为。或者是吗?
答案 0 :(得分:8)
此代码存在一些问题。
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;
}
}
}
编辑:我建议接受FredOverflow的回答。它比上述更简单,更快捷。
答案 1 :(得分:6)
从矢量或字符串逐个擦除元素具有二次复杂性。有更好的线性复杂解决方案:
#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;
}
答案 2 :(得分:4)
存储在end
中的先前s.end()值在s.erase()之后无效。因此,不要使用它。
答案 3 :(得分:1)
注意basic_string的语义及它的迭代器。
来自www.ski.com/tech/stl
另请注意,根据C ++标准,basic_string具有非常不寻常的迭代器失效语义。迭代器可能通过交换,保留,插入和擦除(以及等效于插入和/或擦除的函数,例如清除,调整大小,追加和替换)而无效。但是,第一次调用任何非const成员函数(包括非const版本的begin()或operator [])可能会使迭代器无效。 (这些迭代器失效规则的目的是为实现者提供更大的实现技术自由。)
如果
,会发生什么 beg = s.erase(beg);
返回等效于end()
的迭代器答案 4 :(得分:1)
在调用擦除操作时,存储的结束迭代器指针变为无效。因此,在while循环条件中使用s.end()函数
答案 5 :(得分:0)
你必须从.end() - 1迭代到.begin()。同时,使用除==和!=。
之外的比较运算符是不安全的这是我的代码:
vector<long long> myVector (my, my+myCount);
//sort and iterate through top correlation data counts
sort (myVector.begin(), myVector.end());
cout << endl;
int TopCorrelationDataCount = 0;
bool myVectorIterator_lastItem = false;
vector<long long>::iterator myVectorIterator=myVector.end()-1;
while (true) {
long long storedData = *myVectorIterator;
cout << TopCorrelationDataCount << " " << storedData << endl;
//prepare for next item
TopCorrelationDataCount++;
//if (TopCorrelationDataCount >= this->TopCorrelationDataSize) break;
if (myVectorIterator_lastItem) break;
myVectorIterator--;
if (myVectorIterator==myVector.begin())
{
myVectorIterator_lastItem = true;
}
}
注意:使用普通的for不能完成,因为你必须找出if ==。begin()。如果是,这将是您的最后一次迭代。你无法检查是否==。begin() - 1,因为它会导致运行时错误。
如果您只想使用向量中的X项,请使用TopCorrelationDataCount。