-->

C ++流的困惑:istreambuf_iterator VS istream_iterator?C

2019-05-14 01:27发布

是什么区别istreambuf_iteratoristream_iterator ? 而在一般情况是什么流和streambuf之间的区别? 我真的找不到这方面的任何明确的解释,以便决定在这里问。

Answer 1:

IOSTREAMS使用streambuf到作为输入/输出的其源/目标。 实际上,在流缓冲,家人所做的所有关于IO和iostream的家庭工作仅用于格式化和串/从字符串转换。

现在, istream_iterator需要一个模板参数,说什么从流缓冲的无格式字符串序列的格式应为,像istream_iterator<int>会解释(空格分隔)所有传入的文本int秒。

在另一方面, istreambuf_iterator只关心直接通过的相关流缓冲的原始字符和迭代istream ,它被传递。

一般来说,如果你只是在原始字符感兴趣,请使用istreambuf_iterator 。 如果你有兴趣的格式输入,使用istream_iterator

所有我说的话也适用于ostream_iteratorostreambuf_iterator



Answer 2:

Here's a really badly kept secret: an iostream per se, has almost nothing to do with actually reading or writing from/to a file on your computer.

An iostream basically acts as a "matchmaker" between a streambuf and a locale:

The iostream stores some state about how conversions should be done (e.g., the current width and precision for a conversion). It uses those to direct the locale how and where to do a conversion (e.g., convert this number to a string in that buffer with width 8 and precision 5).

Although you didn't ask directly about it, the locale in its turn is really just a container--but (for rather an oddity) a typesafe heterogeneous container. The things it contains are facets. A facet object defines a single facet of an overall locale. The standard defines a number of facets for everything from reading and writing numbers (num_get, num_put) to classifying characters (the ctype facet).

By default, a stream will use the "C" locale. This is pretty basic--numbers are just converted as a stream of digits, the only things it recognizes as letters are the 26 lower case and 26 upper case English letters, and so on. You can, however, imbue a stream with a different locale of your choice. You can choose locales to use by names specified in strings. One that's particularly interesting is one that's selected by an empty string. Using an empty string basically tells the runtime library to select the locale it "thinks" is the most suitable, usually based on how the user has configured the operating system. This allows code to deal with data in a localized format without being written explicitly for any particular locale.

So, the basic difference between an istream_iterator and an istreambuf_iterator is that the data coming out of an istreambuf_iterator hasn't gone through (most of the) transformations done by the locale, but data coming out of an istream_iterator has been transformed by the locale.

For what it's worth, that "most of the" in the previous paragraph is referring to the fact that when you read data from an istreambuf (via an iterator or otherwise) one little bit of locale-based transformation is done: along with various "formatting" kinds of things, the locale contains a codecvt facet, which is what's used to convert from some external representation to some internal representation (e.g., UTF-8 to UTF-32).

It may make more sense to ignore the fact that they're both stored in a locale, and think only of the individual facets involved:

So that's the real difference between a istream_iterator and an istreambuf_iterator. A little bit of transformation is (at least potentially) done to the data from either one, but substantially less is done to the data coming from an istreambuf_iterator.



文章来源: C++ streams confusion: istreambuf_iterator vs istream_iterator?