使用std :: ifstream的std :: istreambuf_iterator“peek”

时间:2011-06-13 01:32:19

标签: c++ iterator ifstream streambuf

在处理数据流时,我更喜欢用模板和迭代器来编写代码。我常常需要“偷看”下一个角色。为了使代码能够处理无双向迭代器,我有一个看起来像这样的代码片段:

template <class I>
I next(I it) {
    return ++it;
}

显然,这会生成迭代器的副本,递增副本并返回它。除非std::istreambuf_iteratorstd::ifstream上运行,否则这种方式可以很好地工作。例如,给定内容为“test.txt”的文件“ABCD”,以及以下代码:

#include <fstream>
#include <iostream>

template <class I>
I next(I it) {
    return ++it;
}

int main() {
    std::ifstream file("test.txt", std::ios::binary);
    std::istreambuf_iterator<char> it(file);
    std::cout << *next(it) << std::endl;
    std::cout << *it << std::endl;
}

输出结果为:

$ ./test 
B
B

而不是我希望的:

$ ./test 
B
A

换句话说,递增迭代器的一个副本会产生增加全部的净效果!

我意识到文件流迭代器的局限性在于它们只能在与文件关联的读缓冲区中运行。所以可能没有一个完全匹配我想要的解决方案。有办法做我想做的事吗?

3 个答案:

答案 0 :(得分:2)

好吧,它实际上并没有增加所有迭代器,而是使用流,最终具有相同的效果。如果你想要向前看,你需要在流本身AFAIK上这样做。

答案 1 :(得分:0)

你在帖子的标题中提到了“偷看”。 std :: istream有一个peek()方法。 使用它。

答案 2 :(得分:0)

流缓冲区迭代器是一次通过迭代器。您无法向后移动,也不能使用vector::iteratorstring::iterator这样的双向功能。无法创建流迭代器的独立副本,该迭代器独立于任何其他迭代器实例在文件流上运行。这是不可能的,因为流迭代器,无论是否复制,都始终在相同的流对象上工作。复制迭代器不会复制文件流。