3

让我们假设以下内容:

string s("!Hello!'");

我的目的是在s变量中获取,只有“Hello”字符串,IOW我想去掉感叹号。

我尝试了以下方法:

std::remove ( s.begin(), s.end(), '!' );

当我 cout 得到的 s 字符串时,我得到:

Helloo!

这 ”!” 字符已被删除,但字符串的末尾没有移动。

我已经读到我需要从 std::remove 的返回值中取回一个迭代器,但我是 C++ 的新手并且没有成功。

我希望像 char::iterator 这样的东西是有效的,但似乎不是......所以

char::iterator new_end;
new_end = std::remove ( s.begin(), s.end(), '!' );
cout << new_end ;

做不到。

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

4

3 回答 3

9

std::remove迭代器上运行,而不是容器。因此,它无法调整容器的大小。

您应该使用擦除删除成语

s.erase(std::remove(s.begin(), s.end(), '!'), s.end());

在这里,remove实现删除逻辑并返回一个迭代器到序列中新的最后一个元素——换句话说,它重新排序元素但不接触容器。erase,最后,通过将容器的结尾设置为remove返回的内容来调整容器的大小。

于 2012-05-21T12:18:13.917 回答
2

迭代器表示容器中的位置。它们的设计与 C 中指向数组元素的指针具有相似的语义。“结束”迭代器通常表示容器中最后一个元素之后的位置,它是一个有效的迭代器,但它不能被取消引用(你不能使用运营商)

为了从容器中删除元素,您必须先使用 remove 再使用erase。这是一个方便的实用程序函数,您可以使用它从集合中删除值。

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, '!');
于 2012-05-21T12:30:20.387 回答
0

虽然其他人已经向您展示了一个解决方案,但建议您查看 Scott Meyer 的“理解为什么删除并没有真正删除任何东西”(在页面中间的某个地方——整个页面让阅读变得有趣,顺便说一句)。

于 2012-05-21T16:45:25.757 回答