istream_iterator:采取额外的输入

时间:2010-11-11 17:15:06

标签: c++ stl iterator istream

我不能让这个爆炸的东西正常工作。问题是,如果我想输入2个数字,我实际上必须输入3.有什么问题?

namespace MT
{
    template<class IIT, class OIT>
    OIT copy_n(IIT iitBegin, size_t szCount, OIT oitBegin)
    {   
        for(size_t szI = 0; (szI < szCount); ++szI)
        {   
            *oitBegin++ = *iitBegin++;
        }   

        return oitBegin;
    }   
};

int main()
{
    vector<int> vNumbers;
    vector<char> vOperators;
    int iNumCount = 0;
    int iNumOperators = 0;

    cout << "Enter number of number(s) :) :\n";
    cin >> iNumCount;
    cout << "Enter number of operator(s) :\n";
    cin >> iNumOperators;

    int iNumber;
    cout << "Enter the " << iNumCount << " number(s):\n";
    MT::copy_n(istream_iterator<int>(cin), iNumCount, back_inserter(vNumbers));

    char cOperator;
    cout << "\nEnter the " << iNumOperators << " operator(s):\n";
    MT::copy_n(istream_iterator<char>(cin), iNumOperators, back_inserter(vOperators));

    copy(vNumbers.begin(), vNumbers.end(), ostream_iterator<int>(cout, " "));
    cout << endl;
    copy(vOperators.begin(), vOperators.end(), ostream_iterator<char>(cout, " "));
    cout << endl;

    return 0;
}

3 个答案:

答案 0 :(得分:3)

将您的流迭代器循环更改为:

    for(size_t szI = 0; (szI < szCount); ++szI)
    {   
        *oitBegin = *iitBegin;
        if (szI < szCount - 1)
        {
          ++oitBegin;
          ++iitBegin;
        }
    }   

答案 1 :(得分:2)

问题是istream_iterator在取消引用时读取不是,而是在它被递增时读取:

  • 构建istream_iterator时读取第一个值
  • 当迭代器递增时,copy_n会读取iNumCount附加值

换句话说,你有一个iiBegin++太多,它会读取一个被丢弃的值。在任何经典迭代器上,这最后一个增量会让你“超越结束”,但是在这里它会触发标准输入的不需要的读取(显然没有结束)。

[编辑] 可能的解决方案:

template<class IIT, class OIT>
OIT copy_n(IIT iitBegin, size_t szCount, OIT oitBegin)
{   
  *oitBegin++ = *iitBegin;
  for(size_t szI = 0; (szI < szCount - 1); ++szI)
    *oitBegin++ = *++iitBegin;
  return oitBegin;
}

答案 2 :(得分:0)

我认为问题是你没有传递EOF符号。如果您在Linux下工作,请在插入第二个数字后尝试键入CTRL + D(在Windows下应该是CTRL + Z,但我不确定)。