c ++字符串成员函数substr用法

Tom*_*eit 3 c++ string substring substr

如果我正确理解了substr成员函数,请告诉我?
result = result.substr(0, pos) + result.substr(pos + 1);
它接受来自pos的字符串,0直到(但不包括), remove[i]
然后+ result.substr(pos + 1);连接字符串的其余部分,但不包括字符串/ char remove

string removeLetters2(string text, string remove)
{
    int pos;
    string result = text;

    for (int i = 0; i < remove.length(); i++)
    {
        while (true)
        {
            pos = result.find(remove[i]);                
            if (pos == string::npos)                      
            {
                break;
            }
            else
            {
                result = result.substr(0, pos) +
                result.substr(pos + 1);
            }
        }
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

Seb*_*ach 7

简而言之,你问是否

result = result.substr(0, pos) +
         result.substr(pos + 1);
Run Code Online (Sandbox Code Playgroud)

删除位置上的角色pos,对吧?

简答:

是.

更长的答案:

双参数调用采用起始索引长度(一个参数调用转到字符串的结尾).

它有助于想象这样的字符串:

F o o / B a r
0 1 2 3 4 5 6   <- indices
Run Code Online (Sandbox Code Playgroud)

现在删除/:

F o o / B a r
0 1 2 3 4 5 6   <- indices
1 2 3 |         <- 1st length
      | 1 2 3   <- 2nd length

result = result.substr(0, 3)   <- from index 0 with length 3
       + result.substr(4);     <- from index 4 to end
Run Code Online (Sandbox Code Playgroud)

作为程序员,始终要注意距离/索引和长度之间的差异.

更好:如果索引已知:

您的代码创建了两个新的临时字符串,然后将这些字符串连接成第三个临时字符串,然后将其复制到该字符串中result.

最好要求string擦除(眨眼眨眼)到位:

result.erase(pos,1);
// or by iterator
string::iterator it = ....;
result.erase(it,it+1);
Run Code Online (Sandbox Code Playgroud)

这为string实施者留下了更多的优化自由,实施者可以选择将pos之后的所有字符移动到左边一个.在专门的场景中,这可以通过单个赋值,单个循环和使用x86交换指令的循环内实现.

更好:如果要删除的字符已知:

或者,但我不确定这是否会提供更好的性能,但它可能会提供更好的代码,算法remove_if:

#include <algorithm>

// this would remove all slashes, question marks and dots
....
    std::string foobar = "ab/d?...";
    std::remove_if (foobar.begin(), foobar.end(), [](char c) {
        return c=='/' || c=='?' || '.';
    });
Run Code Online (Sandbox Code Playgroud)

remove_if 接受任何功能对象.

如果只有一个字符,它会变得更容易:

// this would remove all slashes
std::remove (foobar.begin(), foobar.end(), '/');
Run Code Online (Sandbox Code Playgroud)