使用std :: istream_iterator读取最多N个值

时间:2013-09-16 13:03:36

标签: c++

如果我确定我的输入流包含10个值,我可以用

读取它们
std::copy_n(std::istream_iterator<T>(input), 10, output);

如果我不知道我有多少价值,我可以用

阅读所有这些值
std::copy(std::istream_iterator<T>(input), std::istream_iterator<T>(), output);

我的问题是如何阅读最多 10个值。我试图在这里强大抵御I / O错误, 但似乎copy_n将尝试读取输入的结尾(它不知道它应该停止),并且copy不会停止在10个值。我是否必须自己推出copy_at_most

(好吧,显然有一些关于copy_n的混淆:std::istream_iterator<> with copy_n() and friends

2 个答案:

答案 0 :(得分:3)

可悲的是,目前通常无法使用STL算法限制已处理元素的数量。我个人认为std::copy()应该采用两个范围,分别由开始和结束分隔。如果无法到达任何一端,则相应的范围将是无界限的。也就是说,如果有的话,我会按照这样的方式推出自己的copy()算法:

template <typename InIt, typename OutIt>
std::pair<InIt, OutIt>
copy(InIt init, InIt inend, OutIt outit, OutIt outend) {
    for (; init != inend && outit != outend; ++init, ++outit) {
        *outit = *init;
    }
    return std::make_pair(init, outit);
}

要处理当前的迭代器系统,实际上无法完成输出迭代器之间的比较。因此,输出迭代器的比较实际上需要一些模板编程来确保永远不会比较实际的输出迭代器,而是返回true。对于所有其他迭代器类,上述算法应该正常工作(假设我没有引入任何拼写错误)。

答案 1 :(得分:1)

你可以使用copy_if和一个计数器 - 不幸的是,它不会提前破坏。

int count = 0;
std::copy_if(std::istream_iterator<T>(input), std::istream_iterator<T>(), output,
    [&]() { return ++count < 10; });

如果你想坚持使用算法(而不是普通的for循环),我建议你自己动手(我过去回答了similar question。)