【问题标题】:Iterator malfunction when looping through string遍历字符串时迭代器故障
【发布时间】:2017-04-22 00:48:45
【问题描述】:

我要做的是让用户以他们喜欢的格式输入电话号码,然后使用循环将字符串中的每个字符与另一个字符进行比较来删除用户在输入中使用的辅助字符一组已定义的辅助字符,如果匹配,它会从字符串中删除该字符。我这样做是作为一个练习问题来发展我对迭代器的理解。我已经用微不足道的 for 循环成功地做到了这一点。但是,当我尝试以这种方式执行此操作时,每当有两个辅助字符(如“(+”)时,循环不会为下一个字符运行,在这种情况下是“+”。它直接跳到“9 " 并且在那之后工作正常。如果字符串中稍后出现其他帮助字符,它会执行相同的行为。我通过在第一个 for 循环下方放置一个 cout

#include <iostream>
#include <string>

using namespace std;

int main()
{

 string main = "(+91)892-333";
 string dictionary = "(+)-";

 for( string::iterator i = main.begin(); i !=  main.end(); i++)
 {


     for( char word : dictionary)
     {

                if(*i == word)
                {
                    main.erase(i);
                    break;
                }
     }
 }

 cout << main;

}

【问题讨论】:

    标签: string loops c++11 iterator char


    【解决方案1】:

    根据documentation erase 使迭代器无效。所以在你调用erase 之后,你不能使用之前获得的迭代器,否则你会得到 UB。在您的情况下,erase 不会更改迭代器,但如果删除符号后的字符串还剩一个符号,则会移动结尾。所以你的迭代器现在指向下一个字符。但是这种行为并不能保证,std::string 可能会分配新的缓冲区并将数据移动到那里,使旧的迭代器指向无处。

    【讨论】:

    • 得到它添加一个 i-- 在擦除功能就像一个魅力之后,但迭代器不应该失效吗?
    • 在 C++ 上编写时,使用 boost 是很常见的。这是 STL 的游乐场。有 boost/algorithm/string/erase.hpp ,您可以在其中找到完全符合您要求的函数。或者您可以使用 std::remove_if 然后使用 substr 删除未使用的字符串结尾。
    猜你喜欢
    • 1970-01-01
    • 2014-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-17
    • 2016-09-03
    相关资源
    最近更新 更多