zoukankan      html  css  js  c++  java
  • 【C++ Primer 第10章】 10.4.2 插入迭代器

    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。

     1 istream_iterator<T> in(is);     in从输入流is读取类型为T的值
     2 
     3 istream_iterator<T> end;       读取类型为T的值的istream_iterator迭代器,表所尾后位置
     4 
     5 in1 == in2                in1和in2必须读取相同类型。如果它们都是尾后迭代器,或绑定到相同的输入,则两个相等
     6 
     7 in1!= in2
     8 
     9 *in                    返回从流中读取数据
    10 
    11 in->mem                  与(*in).mem的含义相同
    12 
    13 ++in,in++                使用元素类型所定义的>>运算符从输入流中读取下一个值。与以往一样,前置版本返回一个指向递增后迭代器的引用,后置版本返回旧值
     
     

    使用算法操作流迭代器

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

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

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

     1 3 7 9 9  

    输出为:29

     

    2. ostream_iterator操作

    1 ostream_iterator<T> out(os);      out将类型为T的值写到输出流os中
    2 
    3 ostream_iterator<T> out(os, d);     out将类型为T的值写到输出流os中,每个值后面都输出一个d。d指向一个空字符串结尾的字符数组
    4 
    5 out = val                   用<<运算符将val写入到out所绑定的ostream中。val的类型必须与out可写的类型兼容
    6 
    7 *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;
  • 相关阅读:
    SaaS多租户模式数据存储方案比较
    **Apache的Order Allow,Deny 详解
    php使用gd库将文字转换成图片(转)
    [git] warning: LF will be replaced by CRLF | fatal: CRLF would be replaced by LF[ git 处理和修改行结束符(CRLF和LF)]
    解决Linux CentOS中cp -f 复制强制覆盖的命令无效的方法
    【个人专用&入门级】LAMP一键安装包
    【转】负载均衡软件选型
    Apache不重新编译,利用apxs工具给Apache添加模块,如cgi模块
    [Apache手册]Linux环境下配置Apache运行cgi
    phpMyAdmin提示:配置文件权限错误,无法写入!解决方法
  • 原文地址:https://www.cnblogs.com/sunbines/p/9111653.html
Copyright © 2011-2022 走看看