std::string::擦除没有按我预期工作

std::string::erase doesn't work as I expected

本文关键字:工作 string 擦除 std      更新时间:2023-10-16

这里有很多关于用逗号拆分字符串的问题。我正在尝试制作另一个。

#include<iostream>
#include<algorithm>
#include<string>
#include<cctype>
int main()
{
    std::string str1 = "1.11,       2.11,       3.11,       4.11,       5.11,    ";
    str1.erase(std::remove_if(str1.begin(), str1.end(), [](unsigned char x){return std::isspace(x);}));
    std::cout<<"New string = "<<str1<<std::endl;
    return 0;
}

但是我在下面得到了意想不到的输出。

New string = 1.11,2.11,3.11,4.11,5.11, 4.11, 5.11,

我错过了什么吗?

std::remove_if将未删除的元素移动到字符串的前面,并将迭代器返回到要擦除的第一个元素。 使用单个迭代器参数 erase ,它只擦除单个元素。要擦除所有匹配的字符,您需要通过传递迭代器来使用两个参数版本end

str1.erase(
    std::remove_if(
        str1.begin(),
        str1.end(),
        [](unsigned char x){return std::isspace(x);}
    ),
    str1.end() // this was missing
);

如果您想知道为什么末尾有一些非空格字符,std::remove_if不需要保持消除的元素完整,并且其中一些已被覆盖。

有两个基于迭代器的string::erase版本。一个擦除单个字符,另一个擦除范围。您必须添加范围的末尾才能摆脱所有范围。

str1.erase(std::remove_if(str1.begin(), str1.end(),
                          [](unsigned char x){return std::isspace(x);}),
           str1.end());

erase 的调用使用单个迭代器参数重载,该重载会删除 1 个字符。添加str1.end()作为第二个参数,以获得通常的删除+擦除习惯用法。