【问题标题】:Iterate through a string (STL)遍历字符串 (STL)
【发布时间】:2015-01-23 16:38:36
【问题描述】:

我想遍历一个字符串,从第一个元素到最后一个元素,但是当我执行以下代码时:

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

我无法到达最后一个元素。所以我把它改成了:

for (string::iterator i =beads.begin(); i <= beads.end(); i++);

编译器报错,说不能自增,因为beads.end()+1不存在。

我想知道是否有任何优雅的方法可以解决这个问题,以便我可以到达最后一个元素?

更正:

对不起,其实我是在做递减操作。

我把它改成增量操作只是为了让大家更容易看到。我忘记了beads.end() 是一个过去的迭代器。

我实际上使用的是for (string::iterator i =pos; i &gt;= beads.begin(); i--);。因为beads.begin()不是before-the-start操作符,所以不能使用for (string::iterator i =pos; i != beads.begin(); i--);,否则永远不会到达第一个元素。

但是,编译器报告错误为beads.begin()-1 不存在。

如果我正在执行递减迭代,我可以知道如何解决问题吗?

【问题讨论】:

  • 第一个是正确的(但最后的分号有问题)。你是什​​么意思你不能得到最后一个元素?
  • 第一个应该可以。请显示更多代码
  • @0x499602D2 不好意思,其实我是在做递减操作。 for (string::iterator i =pos; i &gt;= beads.begin(); i--)我改成增量操作只是为了方便大家看。我忘记了beads.end() 是一个过去的迭代器。
  • @lxjhk 你能发布一个代表问题的最小程序吗?另外,考虑使用反向迭代器(rbegin()rend()
  • @lxjhk 如果你向后走,那么不要使用iterator,使用reverse_iterator

标签: c++ iterator std


【解决方案1】:

[编辑:感谢 James Kanze 建议使用现有的反向迭代器]

既然std::string 已经通过rbegin()rend() 方法提供了反向迭代器,那么到目前为止最简单的方法就是使用它们——前提是你不需要访问从位置i 开始的字符串,在循环体中以通常的“向前”方向

for (string::reverse_iterator i = beads.rend(); i != beads.rend(); ++i) {
    ...
}

如果做不到,你可以使用

for (string::iterator ii = beads.end(); ii != beads.begin(); --ii) {
    string::iterator i = ii - 1;
    // Use i, NOT ii from now on
}

是的,它很丑。但是唯一避免重复循环体的真正替代方法是引入一个特殊的finalIter 标志变量(同样混乱),或者更改为while 循环:

{
    string::iterator i = beads.end();
    while (i != beads.begin()) {
        --i;
        ...
    }
}

额外的大括号是为了保持i的范围本地化;你可能不需要它们。 [编辑#2:正如 James Kanze 所注意到的,由于我们需要处理空字符串的情况,我们可以使用 while 而不是 if 加上 do ... while。]

【讨论】:

  • 另一种方法是使用索引而不是迭代器。该字符串可以被视为一个字符数组。
  • 我采纳了你的第一个建议。它完美地工作。谢谢。
  • 两个问题:第一,只使用std::string::reverse_iteratorstd::strring::rbeginstd::string::rend 有什么问题?您不需要创建自己的。第二:为什么要使用if,然后是do ... while,而不是简单的while
  • @JamesKanze:哎呀,我没有意识到std::stringrbegin()rend()!我会解决的。回复:只使用while:当i == beads.begin() 时,你将如何允许循环体执行?
  • @j_random_hacker 我对使用while 而不是if 然后do ... while 的评论涉及您的第二个示例。 if 中的条件与do ... while 中的条件相同。
【解决方案2】:

最好的解决方案可能仍然是使用反向迭代器:

for ( auto i = std::string::reverse_iterator( pos ); i != beads.rend(); ++ i ) {
    //  ...
}

这假设您不想遍历pos;是你 这样做,你必须确保它不是beads.end(),然后 用std::string::reverse_iterator( pos + 1 )初始化i

【讨论】:

    猜你喜欢
    • 2018-05-15
    • 2011-08-27
    • 1970-01-01
    • 1970-01-01
    • 2014-12-30
    • 2015-08-26
    相关资源
    最近更新 更多