如何在c ++中使用std :: remove'd字符串?

时间:2012-05-21 12:16:29

标签: c++ string iterator

让我们假设以下内容:

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 ;

没有成功。

任何帮助/指示都将不胜感激!

3 个答案:

答案 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)。