2016-05-12 130 views
3

我试图从后面开始删除std::string中的每个'0'。根据this,有多种方式可以向后迭代器.erase字符串擦除使用向后迭代器追加元素

奇怪的是,它们都将数字附加到std::string,而不是将它们擦除!

这里是一个小样品

//'str' will be "5.090000" 
std::string str = std::to_string(5.09); 

auto it = std::remove_if(str.rbegin(), str.rend(), [](char value) { 
    return value == '0'; 
}); 

1)预C++11方式:

str.erase(--(it.base())); 

2)C++11方式(1)

str.erase(std::next(it).base()); 

3)C++11方式(2 )

std::advance(it, 1); 
str.erase(it.base()); 

在所有情况下,str == "5.095.9"。为什么?因为在我看来,str应该是5.9,但它不是...

我最好的猜测是,我做错了什么与向后迭代,因为如果你分割字符串:5.09 | 5.9,第一个值仍然在'0'之间,但不是最后一个。第二个值实际上是我预期的std::string

我做错了什么?

+2

看性病的'文档:: remove_if'非常小心,想想你操纵的范围内。 –

+0

我从来没有使用后向迭代器,但我的天真猜测是你必须像这样使用它们:'std :: remove_if(str.rend(),str.rbegin(),[](char value)' – user463035818

+0

@KerrekSB我是否会溺爱他行使rtfm? – user463035818

回答

1

我提出在我的方法2米的误差:

  • erase调用时只使用1迭代移除迭代器指向的元素,而不是从迭代结束时(如我错认为)

所以str.erase(std::next(it).base(), str.end()); - 这仍然是错的,请继续阅读;)

  • 作为@KerrekSB指出的那样,我没看过the docs足够小心:因为我使用的是std::reverse_iterator,元素会被推回到前面!因此,当it指向新的结束迭代器(其在之前的未删除元素为BTW )时,我必须从开头(str.begin())到it.base()删除范围。


TL; DR

新的工作版本是:str.erase(str.begin(), it.base());