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

C++ 如何将N个整数读入向量?,c++,vector,input,C++,Vector,Input,如果我想读取标准输入到向量的所有整数,我可以使用方便的: vector<int> v{istream_iterator<int>(cin), istream_iterator()}; 或者是否还有其他右手操作的方法?如评论中所述,copy\n对于此作业不安全,但您可以使用copy\u,如果具有可变lambda: #include <iterator> #include <vector> #include <iostream> #inc

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

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

或者是否还有其他右手操作的方法?

如评论中所述,
copy\n
对于此作业不安全,但您可以使用
copy\u,如果
具有可变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;
}
#包括
#包括
#包括

#include

您通常不应该使用
std::copy\n
执行此操作,它假定提供的迭代器在递增n倍时仍然有效:

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

()

如果你能保证这一点,那就好了,但通常使用
std::cin
是不可能的。您可以很容易地让它取消对无效迭代器的引用:

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

()

虽然我可能会使用更强的终止条件来避免从“死”流中进行过多读取,但您的循环基本上就是这样:

您可以这样使用它:

copy_atmost_n(
   std::istream_iterator<int>(std::cin),
   std::istream_iterator<int>(),
   N,
   std::back_inserter(v)
);
copy\u atmost\n(
std::istream_迭代器(std::cin),
std::istream_迭代器(),
N
标准:背面插入器(v)
);
现在得到M个元素,其中M是提供的输入数或N,以较小者为准


()如果没有提供足够的输入,是否会导致UB?您无法修复它
std::copy_n
不适合此任务。仍然不适合。取消引用
std::istream_迭代器
“end迭代器”具有UB,而不是throw语义。(见我的答案)@bartop我建议删除
copy\n
部分,并按照注释中给出的那样离开,copy\n是不安全的,但是你可以使用copy\if和可变lambda:然后是你的好解决方案。带有
copy\u if
的版本更好(删除下一票)。从技术上讲,不能保证谓词会被称为“按顺序”,但我们可以保证它会被精确地多次调用,并且没有很好的实际理由将其称为无序。所以这应该行得通。尽管如此,像my
copy\u atmost\n
这样的包装器更简洁、更具表现力,更容易获得正确的结果。可能的重复为了确认我正确地解释了这个答案,
copy\n
的问题是,如果流在读取n个元素之前遇到问题,行为是未定义的?因此,基本上,“如果您信任您的数据源,请尝试使用它,但如果您不信任,请不要使用
copy\n
?”@templatetypedef——如果您“尝试”,我想您会在每个步骤上保存一个迭代器比较。但对于一般用途,我将从此处使用
copy\u atmost\n
tbh@templatetypedef注意,我特别想到了EOF——tbh我不确定如果有数据但读取/解析失败会发生什么
vector<int> v(n);
for(vector<int>::size_type i = 0; i < n; i++)
    if (!cin >> v[i])
       break;
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)
);