如何将N个整数读入向量?

时间:2019-01-18 12:30:06

标签: c++ vector input

如果我想从标准输入到向量读取所有个整数,可以使用方便的方法:

vector<int> v{istream_iterator<int>(cin), istream_iterator()};

但是,假设我只想读取n整数。我所有的手环都是吗?

vector<int> v(n);
for(vector<int>::size_type i = 0; i < n; i++)
    cin >> v[i];

或者还有其他右手方法吗?

2 个答案:

答案 0 :(得分:12)

如注释中所述,copy_n对于此作业是不安全的,但是您可以对可变的lambda使用copy_if

#include <iterator>
#include <vector>
#include <iostream>
#include <algorithm>

int main(){
    const int N = 10;
    std::vector<int> v;
    //optionally v.reserve(N);
    std::copy_if(
        std::istream_iterator<int>(std::cin),
        std::istream_iterator<int>(), 
        std::back_inserter(v), 
        [count=N] (int)  mutable {
            return count && count--;
    });

    return 0;
}

在此答案中指出: std::copy n elements or to the end

答案 1 :(得分:11)

通常不应该使用std::copy_n进行此操作,它假定所提供的迭代器在 n 次递增时仍然有效:

  

count开始的范围到first开始的范围精确复制result值。形式上,对于每个非负整数i < n,执行*(result + i) = *(first + i)

     

cppreference.com article on std::copy_n

如果可以保证的话,那么可以,但是通常使用std::cin是不可能的。您可以很容易地取消对无效迭代器的引用:

  

默认构造的std::istream_iterator被称为流结束迭代器。当有效的std::istream_iterator到达基础流的末尾时,它等于流的结束迭代器。取消引用或递增它会进一步调用未定义的行为。

     

cppreference.com article on std::istream_iterator

尽管您可能会使用更强的终止条件来避免从“死”流中读取过多内容,但是您的循环几乎在那儿了:

vector<int> v(n);
for(vector<int>::size_type i = 0; i < n; i++)
    if (!cin >> v[i])
       break;

我很想把它包装成类似std::copy_n的东西,但是除了从 0 N 。

一个实现可能看起来像:

template<class InputIt, class Size, class OutputIt>
OutputIt copy_atmost_n(InputIt first, InputIt last, Size count, OutputIt result)
{
   for (Size i = 0; i < count && first != last; ++i)
      *result++ = *first++;
   return result;
}

您将像这样使用它:

copy_atmost_n(
   std::istream_iterator<int>(std::cin),
   std::istream_iterator<int>(),
   N,
   std::back_inserter(v)
);

现在您将获得 M 个元素,其中 M 是提供的输入数量或 N 中较小的一个。

live demo