让我们假设以下内容:
string s("!Hello!'");
我的目标是在s变量中获取只有“Hello”字符串,IOW我想删除感叹号。
我尝试了以下内容:
std::remove ( s.begin(), s.end(), '!' );
当我输出结果的字符串时,我得到:
Helloo!
“!”字符已被删除,但字符串的末尾未被移动。
我已经读过我需要从std :: remove的返回值返回一个迭代器,但我是C ++中的新手并且没有成功。
我希望像char :: iterator这样的东西是有效的,但似乎不是......所以
char::iterator new_end;
new_end = std::remove ( s.begin(), s.end(), '!' );
cout << new_end ;
没有成功。
任何帮助/指示都将不胜感激!
答案 0 :(得分:9)
std::remove
对 iterators 进行操作,而不是容器。因此,它无法调整容器的大小。
您应该使用erase-remove idiom:
s.erase(std::remove(s.begin(), s.end(), '!'), s.end());
这里,remove
实现了删除逻辑,并将迭代器返回到序列中新的最后一个元素 - 换句话说,它重新排序元素但不触及容器。最后,erase
通过将容器的结尾设置为remove
返回来调整容器的大小。
答案 1 :(得分:2)
迭代器代表容器中的位置。它们的设计与C中数组元素的指针具有相似的语义。“end”迭代器通常表示容器中最后一个元素之后的位置,它是一个有效的迭代器,但它不能被解引用(你不能使用它) '*'运算符)
要从容器中删除元素,您必须使用remove,然后删除。这是一个方便的实用程序函数,您可以使用它来删除集合中的值。
template<typename Collection, typename Element>
void remove_elements(Collection& c, const Element& e) {
c.erase(std::remove(c.begin(), c.end(), e), c.end());
};
现在你可以写:
remove_elements(s, '!');
答案 2 :(得分:0)
虽然其他人已经向您展示了解决方案,但建议您查看Scott Meyer的“Understanding why remove doesn’t really remove anything”(在页面中间的某个位置 - 整个页面可以进行有趣的阅读,BTW)。