iostream迭代器

标准库为iostream定义了可用于这些IO类型对象的迭代器。 istream_iterator读取输入流, ostream_iterator向一个输出流写数据。
 

1. istream_iterator操作

当创建一个流迭代器时,必须指定迭代器将要读写的对象类型。一个istream_iterator使用 >> 来读取流。因此,istream_iterator要读取的类型必须定义了 >> 运算符。
 
创建一个istream_iterator时,我们可以将它绑定到一个流。
istream_iterator<int>  int_it(cin);   // 从cin读取string
istream_iterator<int> int_eof ifstream in("afile");
istream_iterator<string> str_it(in); // 从 "afile"读取string
istream_iterator<int> in_iter(cin); //从cin读取int
istream_iterator<int> eof; //istream尾后迭代器 while(in_iter != eof)
  //后置递增运算读取流,返回迭代器的旧值
  //解引用迭代器,获得从流读取的前一个值
  vec.push_back(*in_iter++);

此循环从cin读取int值,保存在vec中。在每个循环步中,循环体代码检查in_iter是否等于eof。eof被定义为空istream_iterator,从而可以当作尾后迭代器来使用。对于一个绑定到流的迭代器,一旦其关联的流遇到文件尾或遇到IO错误,迭代器的值就与尾后迭代器相等。

我们可以将程序重写为如下形式,这体现了istream_iterator更有用的地方:

istream_iterator<int> in_iter(cin),eof;   //从cin读取int
vector<int> vec(in_iter, eof); //从迭代器范围构造vec

本例中我们使用了一对表示范围的迭代器来构造vec,这两个迭代器是istream_iterator,这意味着元素范围是通过从关联的流中读取数据获得的。这个构造函数从cin读取数据,直至遇到文件尾或者遇到一个不是int的数据为止。从流中读取的数据被用来构造vec。

 istream_iterator<T> in(is);     in从输入流is读取类型为T的值

 istream_iterator<T> end;       读取类型为T的值的istream_iterator迭代器,表所尾后位置

 in1 == in2                in1和in2必须读取相同类型。如果它们都是尾后迭代器,或绑定到相同的输入,则两个相等

 in1!= in2

 *in                    返回从流中读取数据

 in->mem                  与(*in).mem的含义相同

 ++in,in++                使用元素类型所定义的>>运算符从输入流中读取下一个值。与以往一样,前置版本返回一个指向递增后迭代器的引用,后置版本返回旧值
 
 

使用算法操作流迭代器

由于算法使用迭代器操作来处理数据,而流迭代器又至少支持某种迭代器操作,因此我们至少可以用某些算法来操作流迭代器。下面是一个例子,我们可以用一对istream_iterator来调用accumulate:

istream_iterator<int> in(cin), eof;
cout<< accumulatre(in,eof,) << endl;

此调用会计算出从标准输入读取的值的和。如果输入为:

输出为:29

 

2. ostream_iterator操作

 ostream_iterator<T> out(os);      out将类型为T的值写到输出流os中

 ostream_iterator<T> out(os, d);     out将类型为T的值写到输出流os中,每个值后面都输出一个d。d指向一个空字符串结尾的字符数组

 out = val                   用<<运算符将val写入到out所绑定的ostream中。val的类型必须与out可写的类型兼容

 *out, ++out, out++             这些运算符是存在的,但不对out做任何事情。每个运算符都返回out

我们可以使用ostream_iterator来输出值的序列:

ostream_iterator<int> out_iter(cout," ");
for(auto e:vec)
  *out_iter++=e; //赋值语句实际上将元素写到cout
cout<<endl;

此程序将vec中的每个元素写到cout,每个元素加一个空格,每次向out_iter赋值时,写操作就会被提交。

值得注意的是,当我们向out_iter赋值时,可以忽略解引用和递增运算。即,循环可以重写成下面的样子:

for(auto e: vec)
  out_iter = e; //赋值语句将元素写到cout
cout<<end;

运算符*和++实际上对ostream_iterator对象不做任何事情,因此忽略它们对我们的程序没有任何影响。但是,推荐第一种形式。在这种写法中,流迭代器的使用与其他迭代器的使用保存一致。如果想将此循环改为操作其他迭代器类型,修改起来非常容易。而且,对于读者来说,此循环的行为也更为清晰。

可以通过调用copy来打印vec中的元素,这比编写循环更为简单:

copy(vec.begin(),vec.end(),out_iter);
cout<<endl;

【C++ Primer 第10章】 10.4.2 插入迭代器的更多相关文章

  1. JavaScript编程艺术-第10章-10.2-实用的动画

    10.2-实用的动画 ***代码亲测可用*** HTML: <!DOCTYPE HTML> <html> <head> <meta charset=" ...

  2. JavaScript编程艺术-第10章-10.1-动画

    10.1—最简单的动画 ***代码亲测可用*** 动画:让元素位置随着时间而不断地发生变化 HTML: <!DOCTYPE HTML> <html> <head> ...

  3. C++ Primer 第三章 标准库类型vector+迭代器iterator 运算

    1.vector: 标准库类型vector表示对象的集合,其中所有对象的类型都相同,集合中的每个对象都有一个与之对应的索引,索引用于访问对象.因为vector“容纳着”其他对象,所以它也常被称作容器( ...

  4. 孙鑫视频学习:对第10章设置线宽时为什么不调用UpDateData(TRUE)的理解

    在第10章10.2.1小节中,首先分别对视图类和对话框类添加了一个名为m_nLineWidth的int型变量,再将用户在CSetting dlg对话框的edit控件中输入的线宽值记录在dlg.m_nL ...

  5. 【c++ Prime 学习笔记】第10章 泛型算法

    标准库未给容器添加大量功能,而是提供一组独立于容器的泛型算法 算法:它们实现了一些经典算法的公共接口 泛型:它们可用于不同类型的容器和不同类型的元素 利用这些算法可实现容器基本操作很难做到的事,例如查 ...

  6. C++ Primer 读书笔记:第10章 关联容器

    第10章 关联容器 引: map set multimap multiset 1.pair类型 pair<string, int> anon anon.first, anon.second ...

  7. C++ primer plus读书笔记——第10章 对象和类

    第10章 对象和类 1. 基本类型完成了三项工作: 决定数据对象需要的内存数量: 决定如何解释内存中的位: 决定可使用数据对象执行的操作或方法. 2. 不必在类声明中使用关键字private,因为这是 ...

  8. C++ Primer 5th 第10章 泛型算法

    练习10.1:头文件algorithm中定义了一个名为count的函数,它类似find,接受一对迭代器和一个值作为参数.count返回给定值在序列中出现的次数.编写程序,读取int序列存入vector ...

  9. [C++ Primer Plus] 第10章、对象和类(一)程序清单——辨析三个const

    程序清单10.1+10.2+10.3 头文件stock.h #ifndef STOCK00_H_ //先测试x是否被宏定义过 #define STOCK00_H_ //如果没有宏定义,就宏定义x并编译 ...

  10. [C++ Primer] : 第10章: 泛型算法

    概述 泛型算法: 称它们为"算法", 是因为它们实现了一些经典算法的公共接口, 如搜索和排序; 称它们是"泛型的", 是因为它们可以用于不同类型的元素和多种容器 ...

随机推荐

  1. 如何在github上下载单个文件

    原文链接:https://www.cnblogs.com/zhaoqingqing/p/5534827.html 找到目标文件,打开,会看到raw,右键,目标另存为.ok

  2. MySQL邮件使用情况统计方法

    邮件使用情况统计方法如下: ) AS domain, COUNT(DISTINCT [column_name]) AS mail_count, COUNT([column_name]) AS mail ...

  3. Dubbo协议

    参考dubbo官方文档http://dubbo.apache.org/zh-cn/docs/user/references/protocol/dubbo.html dubbo共支持如下几种通信协议: ...

  4. Java编程思想 学习笔记3

    三.操作符 1.优先级 当一个表达式中存在多个操作符时,操作符的优先级就决定了各部分的计算顺序.程序员常常忘记其他优先级规则,所以应该用括号明确规定计算顺序. 当编译器观察到一个String后面紧跟着 ...

  5. Java开发中各种集合框架简介

    在大数据MapReduce作业开发中,我们经常会遇到一些大小表的join,这是如果这个小表足够“小”的话,我们可以使用进行“map-join-side”,这要就可以有效的降低reduce端的压力,但是 ...

  6. K - Find them, Catch them POJ - 1703 (带权并查集)

    题目链接: K - Find them, Catch them POJ - 1703 题目大意:警方决定捣毁两大犯罪团伙:龙帮和蛇帮,显然一个帮派至少有一人.该城有N个罪犯,编号从1至N(N<= ...

  7. [转]OpenBLAS项目与矩阵乘法优化

    课程内容 OpenBLAS项目介绍 矩阵乘法优化算法 一步步调优实现 以下为公开课完整视频,共64分钟: 以下为公开课内容的文字及 PPT 整理. 雷锋网的朋友们大家好,我是张先轶,今天主要介绍一下我 ...

  8. 【转】scapy 构造以太网注入帧

    1. 描述 使用scapy进行以太网帧的注入,相对于RAW_SOCKET还是比较简单的.在讲述packet注入之前,先了解一下scapy伪造以太网帧的相关知识.下图为以太网帧格式和scapy对应的封装 ...

  9. 【转】Python之日志处理(logging模块)

    [转]Python之日志处理(logging模块) 本节内容 日志相关概念 logging模块简介 使用logging提供的模块级别的函数记录日志 logging模块日志流处理流程 使用logging ...

  10. if-else 重构

    最近发现自己写的代码if else太多了,有时候自己回头看都要重新捋逻辑,很不好.决定深入理解下if else重构. 中心思想: ①不同分支应当是同等层次,内容相当. ②合并条件表达式,减少if语句数 ...