std::istreambuf_iterator“查看”与 std::ifstream
在处理数据流时,我更喜欢用模板和迭代器来编写代码。我经常需要“偷看”下一个角色。为了使代码能够处理非双向迭代器,我有一个如下所示的代码片段:
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
在其他中换句话说,增加迭代器的一份副本,具有增加所有迭代器的最终效果!
我意识到文件流迭代器有局限性,因为它们只能对当前与文件关联的读取缓冲区中的内容进行操作。所以可能没有一个解决方案完全符合我想要的。有办法做我想做的事吗?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
好吧,它实际上并没有增加所有迭代器,而是消耗流,这最终具有相同的效果。如果您想提前查看,您需要在流本身上执行此操作,据我所知。
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.
您在帖子标题中提到了“偷看”。 std::istream 有一个 peek() 方法。 使用它。
You mentioned 'peek' in the title of your post. std::istream has a
peek()
method. Use it.流缓冲区迭代器是一次性迭代器。您无法向后移动,并且它不具有诸如
vector::iterator
和string::iterator
等双向功能。无法创建独立于任何其他迭代器实例对文件流进行操作的流迭代器的独立副本。这是不可能的,因为流迭代器,无论是否复制,始终在同一个流对象上工作。复制迭代器不会复制文件流。Stream buffer iterators are one-pass iterators. You cannot move backwards and it doesn't have bidirectional functionality like
vector::iterator
andstring::iterator
to name a few. There is no way to create an isolated copy of a stream iterator which operates on a file stream independent of any other iterator instances. It is impossible because stream iterators, whether copied or not, work on the same stream object all the time. Copying an iterator does not copy the file stream.