標準入力からベクトルにall整数を読みたい場合は、便利な方法を使用できます。
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];
または、これを行うためのより右利きの方法はありますか?
コメントに記載されているように、copy_n
はこのジョブには安全ではありませんが、可変ラムダで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 the end
通常、これを_std::copy_n
_で行うべきではありません。これは、提供された反復子がインクリメントされたときにn回有効であると想定します。
count
で始まる範囲からfirst
で始まる範囲まで正確にresult
値をコピーします。正式には、負でない整数_i < n
_ごとに*(result + i) = *(first + i)
を実行します。(
std::copy_n
_ に関するcppreference.comの記事)
あなたがそれを保証できるなら、それで結構ですが、一般的に_std::cin
_ではそれは不可能です。無効なイテレータを逆参照することは非常に簡単です。
デフォルトで構築された_
std::istream_iterator
_は、ストリームの終わり反復子として知られています。有効な_std::istream_iterator
_が基になるストリームの終わりに到達すると、ストリームの終わり反復子と等しくなります。それを逆参照または増分すると、未定義の動作がさらに呼び出されます。(
std::istream_iterator
_ に関するcppreference.comの記事)
「デッド」ストリームからの過剰な読み取りを回避するために、おそらくより強力な終了条件を使用することになりますが、ループはほとんどあります。
_vector<int> v(n);
for(vector<int>::size_type i = 0; i < n; i++)
if (!cin >> v[i])
break;
_
私は実際にこれを_std::copy_n
_のようなものにラップするように誘惑されますが、から[までのカウントに加えて、境界が検証される完全な「範囲」を受け入れます〜#〜] 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 [〜#〜]、どちらか小さい方。