Std::string::erase()将删除使用Std::string::find()找到的第一个字符之后的所有内容

std::string::erase() erases everything after 1st char found with std::string::find()

本文关键字:Std string 字符 第一个 之后 find erase 删除      更新时间:2023-10-16

我仍然有困难短语标题这个问题,看看这个代码:

#include <iostream>
#include <string>
#include <algorithm>
int main(){
    std::string s1 = " Hello World  1 ";
    std::string s2 = " Hello World  2 ";
    while(s1.find(' ') != std::string::npos){
        s1.erase(s1.find(' '));
    }
    while(s2.find(' ') != std::string::npos){
        s2.erase(std::find(s2.begin() , s2.end() ,' '));
    }
    std::cout<<s1<<"n";
    std::cout<<s2;
    return 0;
}

我使用std::string::find()来检测字符串中空白的存在,如果仍然存在,使用std::string::erase()来删除它们。

我尝试了两种不同的方法:

s1.erase(s1.find(' '));

s2.erase(std::find(s2.begin() , s2.end() ,' '));

然而,在第一个方法中,它在字符串中找到' '空格的第一次出现,并删除它和它后面的所有内容。第二种方法工作正常

当前输出为:

HelloWorld2

谁能告诉我第一个方法删除第一次发生后的所有内容的原因是什么?快速浏览:link

相关链接:

std:: basic_string::找到

std::找到

std:: basic_string::擦除

我使用std::string::find()来检测字符串中空白的存在,如果仍然存在,使用std::string::erase()来删除它们。

每次循环迭代不需要调用find()两次。调用它一次,并将返回值保存为一个变量,然后检查该变量的值,并在需要时将其传递给erase()

我已经尝试了两种不同的方法来做这个

s1.erase(s1.find(' '));

s2.erase(std::find(s2.begin() , s2.end() ,' '));

然而,在第一个方法中,它发现字符串中第一次出现' '空格,并删除它和它后面的所有内容。

阅读您链接到的文档。您正在调用的erase()版本将索引作为其第一个参数:

basic_string& erase( size_type index = 0, size_type count = npos );

当您不指定count值时,它被设置为npos,这告诉erase()从指定的index开始从string删除所有到字符串的结尾。您的string以空格字符开头,因此您正在清除整个字符串,这就是为什么它不出现在输出中。

您需要指定count为1来删除find()发现的空格字符:

do
{
    std::string size_type pos = s1.find(' ');
    if (pos == std::string::npos)
        break;
    s1.erase(pos, 1); //  <-- erase only one character
}
while (true);

或者,您应该使用find()的第二个参数,这样您就可以在上一次迭代结束的地方开始下一个循环迭代。否则,每次都要回到字符串的开头,重新搜索已经搜索过的字符:

std::string::size_type pos = 0;
do
{
    pos = s1.find(' ', pos); // <-- begin search at current position
    if (pos == std::string::npos)
        break;
    s1.erase(pos, 1); // <-- erase only one character
}
while (true);

或者,如果你愿意:

std::string::size_type pos = s1.find(' ');
while (pos != std::string::npos)
{
    s1.erase(pos, 1); // <-- erase only one character
    pos = s1.find(' ', pos); // <-- begin search at current position
}

第二个方法工作正常

您正在调用不同版本的erase():

iterator erase( iterator position );

std::find()返回一个iterator。这个版本的erase()只删除了迭代器所指向的单个字符。

谁能告诉我第一个方法删除的原因是什么一切都在第一次发生之前?

std::basic_string::find 返回找到的子字符串的第一个字符的位置( size_type )或 std::string::npos

因此, s1.erase(s1.find(' ')); 将简单地从位置0擦除到字符串的结尾。注意,第一个循环只执行一次!

您的来电

s1.find(' ')

返回第一个空格的位置,在您的示例中是0。然后调用

s1.erase(s1.find(' ')); // i.e. s1.erase(0);

从位置0擦除到字符串的末尾,因为它调用了重载

basic_string& erase( size_type index = 0, size_type count = npos );

1号。如果您传递1而不是默认的npos

s1.erase(s1.find(' '), 1); // pass 1 instead of default npos

则按预期工作