使用std :: string :: find()找到第一个char后,std :: string :: erase()会删除所有内容

时间:2015-05-27 03:14:36

标签: c++ string c++11

我仍然难以为这个问题说出标题,请看一下这段代码:

std::string::find()

我正在使用std::string::erase()检测字符串中是否存在空格,如果仍然存在,请使用s1.erase(s1.find(' ')); 删除它们。

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

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

' '

然而在第一种方法中,它在字符串中找到HelloWorld2 空格的第一个出现并删除它及其后的所有内容。第二种方法按预期工作。

当前输出为:

SELECT 
    t1.fname,
    t1.lname,
    t3.status,
    t3.amt_2_paid
FROM 
    t1 
    INNER JOIN t2 on t1.info_id = t2.acc_info_id
    INNER JOIN t3 on t2.acc_id = t3.acc_id
    INNER JOIN t4 on t3.bill_id = t4.accnt_bill
WHERE 
    t4.[or] = '01234'

有谁能告诉我第一种方法在第一次出现后删除所有内容的原因是什么?快速浏览一下:link

相关链接:

std::basic_string::find

std::find

std::basic_string::erase

3 个答案:

答案 0 :(得分:4)

  

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

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

  

我尝试了两种不同的方法

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

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

然而在第一种方法中,它在字符串中找到第一个''空格并删除它以及它后面的所有内容。

阅读您关联的documentation。您正在调用erase()的版本,该版本将索引作为其第一个参数:

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

如果您未指定count值,则会将其设置为npos,告知erase()string中移除所有内容从指定的index开始到字符串的结尾。您的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()仅删除迭代器指向的单个字符。

答案 1 :(得分:1)

您的电话

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号from here。 如果您传递1而不是默认npos

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

然后按预期工作。

答案 2 :(得分:1)

  

有谁能告诉我第一种方法删除的原因是什么   一切都在第一次出现之前?

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

因此, s1.erase(s1.find(' ')); 只会从 0 位置删除字符串的 end 。注意第一个循环只执行一次!