C++ STL流缓冲区迭代器(streambuf_iterator)
《C++ STL流迭代器》一节中,讲解了输入流迭代器和输出迭代器的功能和用法,在此基础上,本节继续讲解输入流缓冲区迭代器。
流缓冲区迭代器和流迭代器最大的区别在于,前者仅仅会将元素以字符的形式(包括 char、wchar_t、char16_t 及 char32_t 等)读或者写到流缓冲区中,由于不会涉及数据类型的转换,读写数据的速度比后者要快。
接下来,将一一对它们的功能和用法做讲解。
值得一提的是,该类型迭代器本质是一个输入迭代器,即假设 p 是一个输入流迭代器,则其只能进行 ++p、p++、*p 操作,同时迭代器之间也只能使用 == 和 != 运算符。
另外,实现该类型迭代器的模板类也定义在
1) 通过调用 istreambuf_iterator 模板类中的默认构造函数,可以创建一个表示结尾的输入流缓冲区迭代器。要知道,当我们从流缓冲区中不断读取数据时,总有读取完成的那一刻,这一刻就可以用此方式构建的流缓冲区迭代器表示。
举个例子:
2) 当然,我们还可以指定要读取的流缓冲区,比如:
下面程序演示了输入流缓冲区迭代器的用法:
实际上,该类型迭代器本质上是一个输出迭代器,这意味着假设 p 为一个输出迭代器,则它仅能执行 ++p、p++、*p=t 以及 *p++=t 操作。
另外,和 ostream_iterator 输出流迭代器一样,istreambuf_iterator 迭代器底层也是通过重载赋值(=)运算符实现的。换句话说,即通过赋值运算符,每个赋值给输出流缓冲区迭代器的字符元素,都会被写入到指定的流缓冲区中。
需要指出的是,istreambuf_iterator 类模板也定义在
在此基础上,创建输出流缓冲区迭代器的常用方式有以下 2 种:
1) 通过传递一个流缓冲区对象,即可创建一个输出流缓冲区迭代器,比如:
2) 还可以借助 rdbuf(),传递一个流缓冲区的地址,也可以成功创建输出流缓冲区迭代器:
下面程序演示了输出流缓冲区迭代器的用法:
我们知道在 C++ STL 标准库中,流迭代器又细分为输入流迭代器和输出流迭代器,流缓冲区迭代器也是如此,其又被细分为输入流缓冲区迭代器和输出流缓冲区迭代器:在学习本节之前,读者有必要先了解什么是缓冲区,可阅读《进入缓冲区(缓存)的世界》一节做详细了解。
- 输入流缓冲区迭代器(istreambuf_iterator):从输入流缓冲区中读取字符元素;
- 输出流缓冲区迭代器(ostreambuf_iterator):将连续的字符元素写入到输出缓冲区中。
流缓冲区迭代器和流迭代器最大的区别在于,前者仅仅会将元素以字符的形式(包括 char、wchar_t、char16_t 及 char32_t 等)读或者写到流缓冲区中,由于不会涉及数据类型的转换,读写数据的速度比后者要快。
接下来,将一一对它们的功能和用法做讲解。
C++ STL输入流缓冲区迭代器(istreambuf_iterator)
istreambuf_iterator 输入流缓冲区迭代器的功能是从指定的流缓冲区中读取字符元素。值得一提的是,该类型迭代器本质是一个输入迭代器,即假设 p 是一个输入流迭代器,则其只能进行 ++p、p++、*p 操作,同时迭代器之间也只能使用 == 和 != 运算符。
另外,实现该类型迭代器的模板类也定义在
<iterator>
头文件,并位于 std 命名空间中。因此,在创建并使用该类型迭代器之前,程序中应包含如下代码:#include <iterator> using namespace std;
创建输入流缓冲区迭代器的常用方式,有以下 2 种:第二行代码不是必需的,但如果不用,则程序中在创建该类型的迭代器时,必须手动注明 std 命名空间(强烈建议初学者使用)。
1) 通过调用 istreambuf_iterator 模板类中的默认构造函数,可以创建一个表示结尾的输入流缓冲区迭代器。要知道,当我们从流缓冲区中不断读取数据时,总有读取完成的那一刻,这一刻就可以用此方式构建的流缓冲区迭代器表示。
举个例子:
std::istreambuf_iterator<char> end_in;其中,<> 尖括号中用于指定从流缓冲区中读取的字符类型。
2) 当然,我们还可以指定要读取的流缓冲区,比如:
std::istreambuf_iterator<char> in{ std::cin };除此之外,还可以传入流缓冲区的地址,比如:
std::istreambuf_iterator<char> in {std::cin.rdbuf()};其中,rdbuf() 函数的功能是获取指定流缓冲区的地址。
无论是传入流缓冲区,还是传入其地址,它们最终构造的输入流缓冲区迭代器是一样的。
下面程序演示了输入流缓冲区迭代器的用法:
#include <iostream> // std::cin, std::cout #include <iterator> // std::istreambuf_iterator #include <string> // std::string using namespace std; int main() { //创建结束流缓冲区迭代器 istreambuf_iterator<char> eos; //创建一个从输入缓冲区读取字符元素的迭代器 istreambuf_iterator<char> iit(cin); string mystring; cout << "向缓冲区输入元素:\n"; //不断从缓冲区读取数据,直到读取到 EOF 流结束符 while (iit != eos) { mystring += *iit++; } cout << "string:" << mystring; return 0; }程序执行结果为:
向缓冲区输入元素:
abc ↙
^Z ↙
string:
abc
C++ STL输出流缓冲区迭代器(ostreambuf_iterator)
和 istreambuf_iterator 输入流缓冲区迭代器恰恰相反,ostreambuf_iterator 输出流缓冲区迭代器用于将字符元素写入到指定的流缓冲区中。实际上,该类型迭代器本质上是一个输出迭代器,这意味着假设 p 为一个输出迭代器,则它仅能执行 ++p、p++、*p=t 以及 *p++=t 操作。
另外,和 ostream_iterator 输出流迭代器一样,istreambuf_iterator 迭代器底层也是通过重载赋值(=)运算符实现的。换句话说,即通过赋值运算符,每个赋值给输出流缓冲区迭代器的字符元素,都会被写入到指定的流缓冲区中。
需要指出的是,istreambuf_iterator 类模板也定义在
<iterator>
头文件,并位于 std 命名空间中,因此使用该类型迭代器,程序中需要包含以下代码:
#include <iterator> using namespace std;
在此基础上,创建输出流缓冲区迭代器的常用方式有以下 2 种:
1) 通过传递一个流缓冲区对象,即可创建一个输出流缓冲区迭代器,比如:
std::ostreambuf_iterator<char> out_it (std::cout);同样,尖括号 <> 中用于指定要写入字符的类型,可以是 char、wchar_t、char16_t 以及 char32_t 等。
2) 还可以借助 rdbuf(),传递一个流缓冲区的地址,也可以成功创建输出流缓冲区迭代器:
std::ostreambuf_iterator<char> out_it (std::cout.rdbuf());
下面程序演示了输出流缓冲区迭代器的用法:
#include <iostream> // std::cin, std::cout #include <iterator> // std::ostreambuf_iterator #include <string> // std::string #include <algorithm> // std::copy int main() { //创建一个和输出流缓冲区相关联的迭代器 std::ostreambuf_iterator<char> out_it(std::cout); // stdout iterator //向输出流缓冲区中写入字符元素 *out_it = 'S'; *out_it = 'T'; *out_it = 'L'; //和 copy() 函数连用 std::string mystring("\nhttps://www.xinbaoku.com/stl/"); //将 mystring 中的字符串全部写入到输出流缓冲区中 std::copy(mystring.begin(), mystring.end(), out_it); return 0; }程序执行结果为:
STL
https://www.xinbaoku.com/stl/
有关 copy() 函数的具体用法,后续章节会做详细讲解。
所有教程
- C语言入门
- C语言编译器
- C语言项目案例
- 数据结构
- C++
- STL
- C++11
- socket
- GCC
- GDB
- Makefile
- OpenCV
- Qt教程
- Unity 3D
- UE4
- 游戏引擎
- Python
- Python并发编程
- TensorFlow
- Django
- NumPy
- Linux
- Shell
- Java教程
- 设计模式
- Java Swing
- Servlet
- JSP教程
- Struts2
- Maven
- Spring
- Spring MVC
- Spring Boot
- Spring Cloud
- Hibernate
- Mybatis
- MySQL教程
- MySQL函数
- NoSQL
- Redis
- MongoDB
- HBase
- Go语言
- C#
- MATLAB
- JavaScript
- Bootstrap
- HTML
- CSS教程
- PHP
- 汇编语言
- TCP/IP
- vi命令
- Android教程
- 区块链
- Docker
- 大数据
- 云计算