52

istreambuf_iterator和 和有什么不一样istream_iterator?一般来说,流和流缓冲区有什么区别?我真的找不到任何明确的解释,所以决定在这里问。

4

2 回答 2

58

IOstreams 使用 streambufs 作为输入/输出的源/目标。实际上,streambuf-family 完成了有关 IO 的所有工作,而 IOstream-family 仅用于格式化和 to-string / from-string 转换。

现在,istream_iterator接受一个模板参数,该参数说明来自 streambuf 的未格式化字符串序列应该被格式化为什么格式,就像istream_iterator<int>将所有传入文本(空格分隔)解释为ints。

另一方面,istreambuf_iterator只关心原始字符并直接迭代istream它所传递的相关流缓冲区。

通常,如果您只对原始字符感兴趣,请使用istreambuf_iterator. 如果您对格式化的输入感兴趣,请使用istream_iterator.

我所说的所有内容也适用于ostream_iteratorand ostreambuf_iterator

于 2012-05-12T13:16:48.687 回答
20

这是一个非常保守的秘密:一个 iostream本身,几乎与实际读取或写入计算机上的文件无关。

iostream 基本上充当 streambuf 和语言环境之间的“媒人”:

在此处输入图像描述

iostream 存储一些关于应该如何进行转换的状态(例如,转换的当前宽度和精度)。它使用这些来指导语言环境如何以及在何处进行转换(例如,将此数字转换为该缓冲区中宽度为 8 和精度为 5 的字符串)。

尽管您没有直接询问它,但反过来,语言环境实际上只是一个容器——但(相当奇怪)一个类型安全的异构容器。它包含的东西是facets。一个 facet 对象定义了整个语言环境的一个 facet。该标准为从读取和写入数字(num_get, num_put)到分类字符(ctype 方面)的所有内容定义了许多方面。

默认情况下,流将使用“C”语言环境。这是非常基本的——数字只是转换为数字流,它识别为字母的唯一内容是 26 个小写和 26 个大写英文字母,依此类推。但是,您可以imbue选择具有不同语言环境的流。您可以通过字符串中指定的名称选择要使用的语言环境。一个特别有趣的是由一个空字符串选择的。使用空字符串基本上告诉运行时库选择它“认为”最合适的语言环境,通常基于用户如何配置操作系统。这允许代码以本地化格式处理数据,而无需为任何特定语言环境明确编写。

istream_iterator因此,an和 an之间的基本区别在于istreambuf_iterator,来自 istreambuf_iterator 的数据没有经历(大部分)由语言环境完成的转换,但来自 an 的数据istream_iterator已经通过语言环境进行了转换。

值得一提的是,上一段中的“大部分”指的是当您从 istreambuf(通过迭代器或其他方式)读取数据时,完成一点基于区域设置的转换:以及各种“格式化”类型的东西,语言环境包含一个 codecvt facet,它用于将一些外部表示转换为一些内部表示(例如,UTF-8 到 UTF-32)。

忽略它们都存储在语言环境中这一事实可能更有意义,而只考虑所涉及的各个方面:

在此处输入图像描述

istream_iterator这就是 a和 an之间的真正区别istreambuf_iterator。(至少可能)对来自任何一个的数据进行了一点转换,但来自istreambuf_iterator.

于 2015-12-24T21:23:05.283 回答