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

Using std::istream_iterator to read up to N values

本文关键字:读取 个值 iterator std istream 使用      更新时间:2023-10-16

如果我确定我的输入流包含 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<> 与 copy_n() 和朋友)

可悲的是,目前通常没有办法限制使用 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。对于所有其他迭代器类,上述算法应该可以正常工作(假设我没有引入任何拼写错误)。

您可以使用

copy_if和计数器 - 不幸的是,它们不会早点中断。

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

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