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

gaa*_*kam 18 c++ input vector

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

vector<int> v{istream_iterator<int>(cin), istream_iterator()};
Run Code Online (Sandbox Code Playgroud)

但我们假设我只想读取n整数.手动打字循环是我得到的一切吗?

vector<int> v(n);
for(vector<int>::size_type i = 0; i < n; i++)
    cin >> v[i];
Run Code Online (Sandbox Code Playgroud)

还是有更多的右手方式来做到这一点?

bar*_*top 12

正如评论中所给出的,copy_n这项工作不安全,但你可以使用copy_ifmutable lambda:

#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;
}
Run Code Online (Sandbox Code Playgroud)

正如在这个答案中所指出的: std :: copy n元素或者到底

  • 如果没有提供足够的输入,是否会导致UB? (7认同)
  • 仍然没有.解除引用`std :: istream_iterator`"end iterator"具有UB,而不是抛出语义.(见我的回答) (3认同)
  • 你无法解决它.`std :: copy_n`不适合这个任务. (2认同)

Lig*_*ica 11

您通常不应该这样做std::copy_n,假设提供的迭代器在增加n次时仍然有效:

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

(cppreference.com上的文章std::copy_n)

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

default-construct std::istream_iterator被称为end-of-stream迭代器.当有效值std::istream_iterator到达底层流的末尾时,它变为等于流末尾迭代器.取消引用或递增它会进一步调用未定义的行为.

(cppreference.com上的文章std::istream_iterator)

虽然我可能会使用更强的终止条件来避免来自"死"流的过多读取,但你的循环几乎就在那里:

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

我会真正动心包装成的东西,是这样的std::copy_n,但其接受范围可以额外验证,计算从一个完整的"范围" 0ñ.

实现可能如下所示:

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;
}
Run Code Online (Sandbox Code Playgroud)

你会这样使用它:

copy_atmost_n(
   std::istream_iterator<int>(std::cin),
   std::istream_iterator<int>(),
   N,
   std::back_inserter(v)
);
Run Code Online (Sandbox Code Playgroud)

现在你得到M个元素,其中M是提供的输入数或N,取较小者.

(现场演示)