std :: istreambuf_iterator "peek" с помощью std :: ifstream - PullRequest
2 голосов
/ 13 июня 2011

При работе с потоками данных я предпочитаю писать код в терминах шаблонов и итераторов. Часто мне нужно «заглянуть» на следующего персонажа. Чтобы код мог работать с двунаправленными итераторами, у меня есть фрагмент, который выглядит следующим образом:

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

Очевидно, что это делает копию итератора, увеличивает ее и возвращает. Это имеет тенденцию работать очень хорошо ... кроме случаев, когда std::istreambuf_iterator работает на std::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 ]

2 голосов
/ 13 июня 2011

Ну, на самом деле он не увеличивает все итераторы, а потребляет поток , что в итоге дает тот же эффект. Если вы хотите заглянуть вперёд, вам нужно сделать это на самом потоке, AFAIK.

0 голосов
/ 22 января 2014

Итераторы потокового буфера являются однопроходными итераторами.Вы не можете двигаться назад, и у него нет двунаправленной функциональности, например, vector::iterator и string::iterator.Невозможно создать изолированную копию потокового итератора, который работает с файловым потоком независимо от любых других экземпляров итератора.Это невозможно, потому что потоковые итераторы, независимо от того, скопированы они или нет, постоянно работают с одним и тем же потоковым объектом.Копирование итератора не копирует поток файла.

0 голосов
/ 13 июня 2011

Вы упомянули 'peek' в заголовке вашего сообщения.std :: istream имеет метод peek(). Используйте это.

...