When dealing with streams of data, I prefer to write the code in terms of templates and iterators. Often I need to "peek" at the next character. In order to make the code be able to deal no-bidirectional iterators, I have a snippet which looks like this:
template <class I>
I next(I it) {
return ++it;
}
Obviously, this makes a copy of the iterator, increments the copy and returns it. This tends to work very nicely... except when the std::istreambuf_iterator
is operating on a std::ifstream
. For example, given a file "test.txt
" with the contents "ABCD
", and the following code:
#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;
}
The output is:
$ ./test
B
B
Instead of what I hoped for:
$ ./test
B
A
In other words, incrementing one copy of the iterator, has the net effect of incrementing all of them!
I realize that file stream iterators have limitations in that they can only operate on what is currently in the read buffer associated with the file. So there may not be a solution which matches exactly what I want. Is there a way to do what I want?
Well, it actually doesn't increment all iterators but rather consumes the stream, which in the end has the same effect. If you want to peek ahead, you need to do so on the stream itself, AFAIK.