10

我正在使用循环来计算输入单词的次数,然后打印该单词以及输入的次数,这有效,但它从不打印最后一个单词,我将其按字母顺序排序。在打印最后一个单词之前,它会出错,指出迭代器不可取消引用。这是我的循环代码:

for (vector<string>::iterator it = v.begin() ; it != v.end(); ++it)
    {
        if (*it == *(it+1))
        {
        count++;
        }
        else if (*it != *(it+1))
        {
                count++;
            cout << *it << " ---- " << count << endl;
            count=0;
        }
    }
4

5 回答 5

21

您的代码具有未定义的行为-想象it指向 的最后一个元素,v然后您尝试取消引用v.end()*(it+1)

if (*it != *(it+1)

STL 迭代器,end 不指向最后一个元素;end() 返回一个迭代器,表示容器中元素的结束。end 是最后一个元素后面的位置。这样的迭代器也称为过去的迭代器

因此,begin() 和 end() 定义了一个包含第一个元素但不包括最后一个元素的半开范围

 --------------------------------
 |  |   |   |   |   |   |   |   |
 --------------------------------
  /\                               /\      
begin()                            end() 

对于您要实现的目标,请查看std::adjacent_find

auto it = std::adjacent_find(v.begin(), v.end());

if (it != v.end())
{
  count ++;
}
else
{
   cout << *it << " ---- " << count << endl;
}
于 2013-09-05T12:58:25.307 回答
2

it == v.end() - 1,你尊重(it+1)so v.end(),而尊重v.end()是未定义的行为。

于 2013-09-05T13:01:27.203 回答
1

当它是结束迭代器之前的一个时,这里有一个问题:*(it+1)因为它试图取消引用结束迭代器,这是无效的。

我不确定在这种情况下你希望你的逻辑做什么,但你可以if (it+1 != v.end())在做你的事情之前检查一下。

于 2013-09-05T13:00:13.543 回答
1

当你在最后一句话并尝试执行时:

if (*it == *(it+1))

it+1指向v.end(),这是一个有效的迭代器,但不可取消引用。因此错误。

于 2013-09-05T12:58:45.830 回答
0

因为何时it接近结束,it+1结束,并且您试图在if运算符中取消引用它。

于 2013-09-05T12:58:30.137 回答