我试图实现一个删除前导和尾随空格的C ++方法
string::iterator begin = s.begin();
string::iterator end = s.end()-1;
while (*begin == ' ') {
cout << "*begin is: " << *begin << endl;
begin++;
}
while (*end == ' ') {
cout << "*end is: " << *end << endl;
end--;
}
s.erase(s.begin(),begin);
s.erase(end+1,s.end());
然后我的代码崩溃了。经过几次调试后,我发现它实际上是由于某种“迭代器错误定位”而引起的。 (当我从字符串中erase()
个元素时,我就把这个名字弄清楚了......不知道这个错误叫做什么... ...所以,如果我这样做(改变程序):
string::iterator begin = s.begin();
while (*begin == ' ') {
cout << "*begin is: " << *begin << endl;
begin++;
}
s.erase(s.begin(),begin);
string::iterator end = s.end()-1;
while (*end == ' ') {
cout << "*end is: " << *end << endl;
end--;
}
s.erase(end+1,s.end());
没有更多问题:D
所以我真的想知道当你使用erase()
元素时迭代器究竟发生了什么。例如,如果您erase()
第一个/最后两个元素,s.end()
/ s.begin()
会发生什么?
答案 0 :(得分:5)
std::string
的要求说:(§[string.require] / 4):
引用basic_string序列元素的引用,指针和迭代器可能会被该basic_string对象的以下用法无效:
[...]
- 调用非const成员函数,除了operator [],at,front,back,begin,rbegin,end和rend。
我只是使用substr
,就像这样:
s = s.substr(begin, end-begin);
我可能也会使用字符串的成员函数来进行搜索:
auto begin = s.find_first_not_of(' ');
auto end = s.find_last_not_of(' ');
s = s.substr(begin, end-begin);
因为它在单个操作中完成了工作,所以它避免了迭代器失效的任何问题(并且作为奖励,它可能会更快一些)。