2016-05-12 111 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());