删除字符串

时间:2016-06-30 14:08:57

标签: c++ string

我想删除字符串中两个相同字符之间的所有字符。我的函数接受一个字符串(通过引用)和参数中的char。

假设我使用std::string这样的变量:"hah haaah hah hello!"作为第一个参数而char [{1}}作为第二个参数,这样的事情应该发生:'h' 。如您所见,两个"hah haaah hah hello!" ===> "hh hh hh hello"个字符之间的每个字符都已被删除。我如何实现这样的目标?

我试过使用迭代器并最终得到了这个:

h

首先,我搜索第一次出现void delete_chars_between(std::string& line, char del) { std::string::iterator itr_from = std::find(line.begin(), line.end(), del); std::string::iterator itr_to = std::find(itr_from + 1, line.end(), del); while (true) { if(itr_to != line.end()) line.erase(itr_from + 1, itr_to); itr_from = std::find(itr_to, line.end(), del); if (itr_from == line.end()) break; itr_to = std::find(itr_from + 1, line.end(), del); if (itr_to == line.end()) break; } } ,我将迭代器存储到del中的位置。之后,我搜索第二次itr_from。最后,如果del有效,我会运行一个while循环,首先擦除某个范围内的字符。我一遍又一遍地重复这一点,而我的迭代器不等于itr_to

但由于某些原因,此代码无法正常运行。它有时会删除空格,甚至不会触及我打算删除的字符。

感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

所有修改字符串长度的操作都会使

std::string迭代器失效,因此在调用itr_from之后使用itr_toline.erase是未定义的行为。

您需要使用erase的返回值:

while (true) {
    if(itr_to != line.end())
        itr_to = line.erase(itr_from + 1, itr_to);

    itr_from = std::find(itr_to, line.end(), del);

    if (itr_from == line.end())
        break;

    itr_to = std::find(itr_from + 1, line.end(), del);

    if (itr_to == line.end())
        break;
}

答案 1 :(得分:0)

为避免未定义的行为,您应在调用erase之前重置两个迭代器。

查看预期输出,似乎不应使用结束分隔符来启动另一个间隔:

"hh hh hh hello"  not  "hhhhhhhello"
   ^  ^  ^

所以,这是我的建议:

void delete_chars_between(std::string& line, char del)
{
    std::string::iterator itr_from = std::find(line.begin(), line.end(), del);
    // I don't want to pass an iterator to two past the last element
    if ( itr_from == line.end() )
        return; 
    std::string::iterator itr_to = std::find(itr_from + 1, line.end(), del);
    //                                               ^^^^

    while ( itr_to != line.end() )
    {
        itr_to = line.erase(itr_from + 1, itr_to);

        itr_from = std::find(itr_to + 1, line.end(), del);
        // to start another couple ^^^^
        if (itr_from == line.end())
            break;

        itr_to = std::find(itr_from + 1, line.end(), del);
    }
}

直播示例HERE

相关问题