istreambuf_iterator
和 和有什么不一样istream_iterator
?一般来说,流和流缓冲区有什么区别?我真的找不到任何明确的解释,所以决定在这里问。
2 回答
IOstreams 使用 streambufs 作为输入/输出的源/目标。实际上,streambuf-family 完成了有关 IO 的所有工作,而 IOstream-family 仅用于格式化和 to-string / from-string 转换。
现在,istream_iterator
接受一个模板参数,该参数说明来自 streambuf 的未格式化字符串序列应该被格式化为什么格式,就像istream_iterator<int>
将所有传入文本(空格分隔)解释为int
s。
另一方面,istreambuf_iterator
只关心原始字符并直接迭代istream
它所传递的相关流缓冲区。
通常,如果您只对原始字符感兴趣,请使用istreambuf_iterator
. 如果您对格式化的输入感兴趣,请使用istream_iterator
.
我所说的所有内容也适用于ostream_iterator
and ostreambuf_iterator
。
这是一个非常保守的秘密:一个 iostream本身,几乎与实际读取或写入计算机上的文件无关。
iostream 基本上充当 streambuf 和语言环境之间的“媒人”:
iostream 存储一些关于应该如何进行转换的状态(例如,转换的当前宽度和精度)。它使用这些来指导语言环境如何以及在何处进行转换(例如,将此数字转换为该缓冲区中宽度为 8 和精度为 5 的字符串)。
尽管您没有直接询问它,但反过来,语言环境实际上只是一个容器——但(相当奇怪)一个类型安全的异构容器。它包含的东西是facet
s。一个 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
.