【问题标题】:std::istreambuf_iterator "peek" with std::ifstreamstd::istreambuf_iterator 用 std::ifstream “窥视”
【发布时间】:2011-06-13 01:32:19
【问题描述】:

在处理数据流时,我更喜欢根据模板和迭代器来编写代码。我经常需要“偷看”下一个角色。为了使代码能够处理非双向迭代器,我有一个如下所示的 sn-p:

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

换句话说,递增迭代器的一个副本,具有递增所有的净效果!

我意识到文件流迭代器的局限性在于它们只能对当前与文件关联的读取缓冲区中的内容进行操作。所以可能没有一个完全符合我想要的解决方案。有没有办法做我想做的事?

【问题讨论】:

    标签: c++ iterator ifstream streambuf


    【解决方案1】:

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

    【讨论】:

    • 是的,我想。这就是我说“净效应”的原因。我认为角色被递增“消耗”了,我只是希望有一些聪明的东西可以做我想做的事。
    • 你需要明确seek它,迭代器不能那样工作。
    【解决方案2】:

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

    【讨论】:

    • 但我想使用迭代器,理想情况下代码将能够使用指针或std::istreambuf_iterator 或任何像迭代器一样工作的东西。
    【解决方案3】:

    流缓冲区迭代器是一次性迭代器。您不能向后移动,并且它没有像 vector::iteratorstring::iterator 这样的双向功能等等。无法创建流迭代器的隔离副本,该副本在独立于任何其他迭代器实例的文件流上运行。这是不可能的,因为流迭代器,无论是否复制,一直在 same 流对象上工作。复制迭代器不会复制文件流。

    【讨论】:

      猜你喜欢
      • 2011-02-23
      • 2011-05-08
      • 1970-01-01
      • 2013-05-09
      • 2017-08-04
      • 2014-03-30
      • 2010-09-26
      • 2010-11-08
      • 1970-01-01
      相关资源
      最近更新 更多