zoukankan      html  css  js  c++  java
  • stream_iterator、ostream_iterator 使用初探

    STL定义了供输入及输出的iostream iterator类,称为 istream_iterator和ostream_iterator,分别支持单一型别的元素的读取和写入。 
    使用方法: 
    1.包含头文件: #include <iterator>  using namespace std;       
    2.像使用其他iterator一样使用istream_iterator和 ostream_iterator。如:
      使用一对“连接至标准输入”的iterator用于标示元素范围: 
       // 将is定义为一个“连接至标准输入装置”的istream_iterator 
       istream_iterator<string> is(cin); 
       // 定义istream_iterator时不为它指定istream对象,它即代表了end-of-file。 
       istream_iterator<string> eof; 
       ostream_iterator<string> os(cout, " "); 
     除了“连接至标准输入”外,还可以连接至其他设备,如文件: 
     
    #include <fstream> 
     using namespace std; 
     ifstream in_file("in.txt"); 
     ofstream out_file("in.txt"); 
     if ( !in_file || !out_file ) 
     { 
             cerr << "failed to open the necessary file! /n"; 
              return -1; 
     } 
     istream_iterator<string> is(in_file); 
     istream_iterator<string> eof; 
     ostream_iterator<string> os(out_file, " "); 


    ***********************************************************************************************
    #include <iostream>   
    #include <iterator>   
    #include <string>   
    #include <vector>   
    #include <fstream>   
    #include <algorithm>   
    using namespace std;  
    int main()  
    {  
        // 1. 标准输入输出操作。   
        istream_iterator<string> is(cin);  
        istream_iterator<string> eof;  
        vector<string> text;  
        // 将标准输入的内容复制至text中。  由于使用的是vector,故使用back_inserter()   
        copy(is, eof, back_inserter(text));    
        // do something.   
        sort(text.begin(), text.end());  
        // 输出至标准输出。   
        ostream_iterator<string> os(cout, " ");  
        copy(text.begin(), text.end(), os);  
        // 2. 非标准输入输出操作:文件读写操作。   
        ifstream in_file("in.txt");  
        ofstream out_file("in.txt");  
        if ( !in_file || !out_file )  
        {  
            cerr << "failed to open the necessary file! /n";  
            return -1;  
        }  
        istream_iterator<string> is2(in_file);  
        istream_iterator<string> eof2;  
        vector<string> text2;  
        copy(is2, eof2, back_inserter(text2));  
    sort(text2.begin(), text2.end());  
        ostream_iterator<string> os2(out_file, " ");  
        copy(text2.begin(), text2.end(), os2);  
        return 0;  
    }  


    ************************************************************************************


    istream_iterator常见错误


    1. 错误原码


    以下原代码不能通过编译:




        ifstream ifs("test.txt");
        istream_iterator<string> ibeg(ifs);
        istream_iterator<string> iend();
        vector<string> vec(ibeg, iend);


    对于vec的构造编译出错:
    error: no matching function for call to `std::vector<std::string, std::allocator<std::string> >::vector(std::istream_iterator<std::string, char, std::char_traits<char>, ptrdiff_t>&, std::istream_iterator<std::string, char, std::char_traits<char>, ptrdiff_t> (&)())'


    原来它把iend当作了一个函数。去掉iend后面的括号就行了:


    2. 正确的完整代码

    #include <iostream>
    #include <iterator>
    #include <fstream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    
    int main()
    {
        ifstream ifs("test.txt");
        istream_iterator<string> ibeg(ifs);
        istream_iterator<string> iend;
        vector<string> vec(ibeg, iend);
    
    
        copy(vec.begin(), vec.end(),ostream_iterator<string>(cout, "
    "));
        return 0;
    }



    3. 直接内嵌出错


    就像在copy函数中一样,并不需要定义ibeg, iend, 应该可以在vector的构造函数中嵌入,如下:


    vector<string> vec(istream_iterator<string>(ifs),istream_iterator<string>);
          
    以上代码当在copy中调用vec.begin(), vec.end()时,就会编译报错:      
    error: request for member `begin' in `vec', which is of non-class type `std::vector<std::string, std::allocator<std::string> > ()(std::istream_iterator<std::string, char, std::char_traits<char>, ptrdiff_t>, std::istream_iterator<std::string, char, std::char_traits<char>, ptrdiff_t>)'
    error: request for member `end' in `vec', which is of non-class type `std::vector<std::string, std::allocator<std::string> > ()(std::istream_iterator<std::string, char, std::char_traits<char>, ptrdiff_t>, std::istream_iterator<std::string, char, std::char_traits<char>, ptrdiff_t>)'


    看来编译器将vec当作了一个函数,而不是一个vector类。
    其中istream_iterator<string>(ifs)
    的括号被编译器忽略了,成为
        vector<string> vec(istream_iterator<string> ifs,
          istream_iterator<string>);


    等同于:
        vector<string> fun(istream_iterator<string> x,
          istream_iterator<string> y);


    4. 访止编译器误解


    就像在加减乘除中用括号指定运算顺序一样,这里也要用括号将构造的临时参数括起来,访止编译器将它们误解为函数中的参数声明。
    同时还要修正一个错误,vec构造函数中的第二个参数构造是错误的,应该加个括号构造一个临时变量。不然对
          istream_iterator<string>);
    报错:
    error: expected primary-expression before ')' token
    因为它只是一个类型声明,而不是一个基本表达式(primary-expression)。


    正确的方法如下:
        vector<string> vec((istream_iterator<string>(ifs)),
          istream_iterator<string>());

        vector<string> vec((istream_iterator<string>(ifs)),
          (istream_iterator<string>()));


    该种方法虽然可行,但还是不用为好,以免某些编译器不支持,同时也增加代码理解难度,而且在更复杂的情形中,这一招也无法解决问题。还是第5种简化方法比较合适
    提示:不管需不需要,稍微复杂一点的表达式都用括号括起来。免得人阅读时出错,或者编译器理解时出错。


    5. 另一种简化方法


    ibeg, iend的定义可以合为一行,可能比内嵌式表达方法更清晰:
        istream_iterator<string> ibeg(ifs), iend;
        vector<string> vec(ibeg, iend); 




    http://blog.csdn.net/rickliuxiao/article/details/6201835


    http://www.cppblog.com/jinq0123/archive/2007/12/12/istream_iterator_ErrorMsg.html

    Keep it simple!
    作者:N3verL4nd
    知识共享,欢迎转载。
  • 相关阅读:
    使用SuperWebSocket 构建实时 Web 应用
    slam for Windows 库安装及应用libfreenect2
    《SLAM十四讲》g2o_custombundle在windows轻松调通
    windows下命令行查看库依赖
    zend studio控制台中文乱码
    http协议转
    mysql 字段 增删改
    PHP内部函数
    分层设计
    SecureCRT上传和下载
  • 原文地址:https://www.cnblogs.com/lgh1992314/p/5834954.html
Copyright © 2011-2022 走看看