istreambuf_iterator
和 istream_iterator
的区别是什么?
并且一般而言,streams 和 streambufs 有什么不同?
我真的找不到任何清晰的解释,所以决定在这里提问。IOstreams使用streambuf作为它们的输入/输出源/目标。实际上,streambuf系列负责处理I/O操作,而IOstream系列仅用于格式化和字符串转换。
现在,istream_iterator
采用一个模板参数来表示从streambuf中提取出的未经格式化的字符串序列应该被格式化为什么类型,例如istream_iterator<int>
会将所有传入的文本(以空白字符分隔)解释为int
。
另一方面,istreambuf_iterator
只关心原始字符,并直接迭代传递给它的istream
相关联的streambuf。
通常情况下,如果您只关心原始字符,请使用istreambuf_iterator
。如果您关心格式化的输入,请使用istream_iterator
。
以上所有内容也适用于ostream_iterator
和ostreambuf_iterator
。
istreambuf_iterator
吗? - Mankarse这是一个非常不好保密的秘密: 实际上,iostream与在您的计算机上读写文件几乎没有任何关系。
iostream基本上只是作为流缓冲区和区域设置之间的“媒人”:
iostream存储了有关如何进行转换的一些状态(例如转换的当前宽度和精度)。 它使用这些状态指导区域设置如何在哪里进行转换(例如,在该缓冲区中将此数字转换为字符串,宽度为 8,精度为 5)。
虽然您没有直接询问,但区域设置实际上只是一个容器--但(出于奇怪性)是一种类型安全的异构容器。 它所包含的内容是facets。 facet对象定义整个locale的一个单独facet。 标准定义了许多facets,用于从读取和写入数字(num_get,num_put)到分类字符(ctype facet)的所有内容。
默认情况下,流将使用“C”区域设置。这很基础--数字只是以数字串的形式转换,它只将26个小写英文字母和26个大写英文字母识别为字母,等等。 但是,您可以使用您选择的不同locale imbue
流。 您可以通过指定字符串中的名称选择要使用的区域设置。 特别有趣的一种是由空字符串选择的一种。 使用空字符串基本上告诉运行时库选择它“认为”最合适的区域设置,通常基于用户如何配置操作系统。 这使得代码能够以本地化格式处理数据,而无需明确编写任何特定的区域设置。
istream_iterator和 istreambuf_iterator
之间的基本区别在于通过 istreambuf_iterator
输出的数据没有经过大部分语言环境执行的转换,但是通过 istream_iterator
输出的数据已经被语言环境转换。
就值得一提的是,在读取来自 istreambuf
(通过迭代器或其他方式)的数据时,会执行一小部分基于语言环境的转换:除了各种“格式化”类型的事情之外,语言环境还包含一个 codecvt
facet,它用于将某些外部表示形式转换为某些内部表示形式(例如,从UTF-8到UTF-32)。
忽略它们都存储在语言环境中可能更有意义,只考虑涉及到的单个facet:
![enter image description here](https://istack.dev59.com/RJX0x.webp)
因此,istream_iterator
和 istreambuf_iterator
之间的真正区别在于对来自任一方的数据都执行了一点转换(至少存在潜在性),但是从 istreambuf_iterator
获得的数据进行的转换较少。
printf
,那就用它吧。如果你想要一个存储原始数据的流缓冲区,你当然也可以这样做(只是不太确定为什么你会问这个问题,如果你并不想要它的话)。 - Jerry Coffin\n
的地方使用std::endl
),否则iostreams在速度上与C I/O相当竞争力。https://dev59.com/THI-5IYBdhLWcg3wTWZu#1926432 - Jerry Coffin