遍历字符串 (STL)

Iterate through a string (STL)

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

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 >= beads.begin(); i--);。因为 beads.begin() 不是开始前运算符,所以我不能使用 for (string::iterator i =pos; i != beads.begin(); i--);,否则我永远不会到达第一个元素。

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

请问如果是递减迭代,请问如何解决?

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

由于事实证明 std::string 已经通过 rbegin() and rend() 方法提供了反向迭代器,到目前为止最简单的方法是使用它们——前提是您不这样做需要在循环体中以通常的 "forward" 方向访问从位置 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.]

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

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

这假定您不想迭代 pos;是你 做,一定要保证不是beads.end(),然后 用 std::string::reverse_iterator( pos + 1 ).

初始化 i