前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >STL之流迭代器

STL之流迭代器

作者头像
用户9831583
发布2022-06-16 14:44:53
5770
发布2022-06-16 14:44:53
举报
文章被收录于专栏:码出名企路

1.输入流

代码实现:

代码语言:javascript
复制
    #include <iostream>                                   
    #include <iterator>  
     #include <algorithm>                                   
    int main()
    {
        std::cout << "Enter some integers - enter Ctrl+Z to end.\n";
        //一个输入流迭代器从 cin 中读取 int 类型的值
        std::istream_iterator<int> iter{std::cin};         
        std::istream_iterator<int> copy_iter{iter};       
        std::istream_iterator<int> end_iter;           
        
        int sum {};
        //第一个循环会求出所有用输入流迭代器读入的值的和,直到识别出 EOF 状态,
        //它是通过从流中读取 Ctrl+Z 标志设置的
        while(iter != end_iter)                           
        {
            sum += *iter++;
        }
        std::cout << "Total is " << sum << std::endl;
        //一句代替for循环

        //std::cout << "Total is " << accumulate(iter, end_iter, 0) <<std::endl;


        //必须调用流对象的 dear() 来重置 EOF 标志
        std::cin.clear();      
        //需要跳过输入缓冲区中留下的 '\n' 字符,通过调用流对象的 ignore 做到                          
        std::cin.ignore();                                 
        
        std::cout << "Enter some more integers - enter Ctrl+Z to end.\n";
        int product{1};
        //读取值并计算它们的 product
        //乘积
        while(true)
        {
            if(copy_iter == end_iter) 
                    break;                
            product *= *copy_iter++;
        }
        std::cout << "product is " << product << std::endl;

         //必须调用流对象的 dear() 来重置 EOF 标志
        std::cin.clear();      
        //需要跳过输入缓冲区中留下的 '\n' 字符,通过调用流对象的 ignore 做到                          
        std::cin.ignore();  
        std::vector<double> data;
        std::cout <<"Enter some numerical values — enter Ctrl+Z to end.\n";
        std::copy(std::istream_iterator<double>{std::cin}, std::istream_iterator <double>{}, 
                    std::back_inserter(data));
        std::copy(std::begin(data), std::end(data), std::ostream_iterator <double>{std::cout, " "});
        std::cout << std::endl;

    }

结果显示:

2.输出流

三种输出流方式:

代码语言:javascript
复制
    #include <iostream>                                     
    #include <iterator>                                     
    #include <vector>                                        
    #include <algorithm>                                     
    #include <string>
    using std::string;
    int main()
    {   
        // 3 种方式将 words 容器中的元素写到标准输出流中
        std::vector<string> words {"The", "quick", "brown", "fox", "jumped", "over", "the", "lazy", "dog"};
        //out_iter1 流迭代器通过调用只以输出流为参数的构造函数而生成。第一个循环以常规方式输出迭代器符号,
        //在解引用后递增它,并复制 word 的当前值到 out_iter1 的解引用的结果中。循环后面的语句会在流中写一个新行。
        std::ostream_iterator<string> out_iter1{std::cout};   
        for(const auto& word : words)
        {
            *out_iter1++ = word;                                 
            *out_iter1++ = " ";                                  
        }
        *out_iter1++ = "\n";   

        //为了保证应用分隔符的第二条赋值语句有输出迭代器作为它的左操作数,语句中的括号是必要的。
        for(const auto& word : words)
        {
            (out_iter1 = word) = " ";                         
        }
        out_iter1 = "\n";                                      
        
        //元素 的值会被复制到 out_iter2 中,定义它的构造函数的第二个参数指定了每个输出值后面的分隔符字符串。
        std::ostream_iterator<string> out_iter2 {std::cout, " "};
        std::copy(std::begin(words), std::end(words), out_iter2);
        out_iter2 = "\n";
    }

结果显示:

3.重载插入和提取运算符

代码实例:

代码语言:javascript
复制
    #include <iostream>                                     
    #include <iterator>                                     
    #include <vector>                                        
    #include <algorithm>                                     
    #include <string>
    using std::string;

        class Name
    {
        private:
            std::string first_name{};
            std::string second_name{};
        public:
            Name() = default;
            Name(const std::string first, const std::string second):first_name{first}, second_name {second} {}
            friend std::istream& operator>>(std::istream& in, Name& name);
            friend std::ostream& operator<<(std::ostream& out, const Name& name);
    };
    
    inline std::istream& operator>>(std::istream& in, Name& name)
    { return in >> name.first_name >> name.second_name; }
   
    inline std::ostream& operator<<(std::ostream& out, const Name& name)
    { return out << name.first_name << ' ' << name.second_name; }


    int main()
    {
            std::cout << "Enter names as first_name second_name. Enter Ctrl+Z on a separate line to end:\n";
            std::vector<Name> names {std::istream_iterator<Name> {std::cin},std::istream_iterator<Name>{}};
            //copy() 算法会将 Name 对象复制到输出流迭代器标识的目的位置,这个迭代器会将对象写到标准输出流中。
            std::copy(std::begin(names),std::end(names) , std::ostream_iterator<Name> {std::cout," "});
    }

结果显示:

4.文件流

表示文件流的类模板:

  • ifstream:表示文件的输出流;
  • ofstream:是为输出定义的文件流;
  • fstream:定义了可以读和写的文件流;

用下面这些定义在 ios_base 类中的常量的组合来指定它们的打开状态:

  • binary:会将文件设置成二进制模式。如果没有设置二进制模式,默认的模式是文本模式。
  • app:在每个写操作(append operation)之前会移到文件的末尾。
  • ate:会在打开文件之后(at the end),移到文件的末尾。
  • in:打开文件来读。对于ifstream和fstream来说,这是默认的。
  • out:打开文件来写。对于ostream和fstream来说,这是默认的。
  • trunc:将当前存在的文件长度截断为0。
4.1文件输入

代码实例:

代码语言:javascript
复制
#include <iostream>                                      
#include <fstream>                                      
#include <iterator>                                      
#include <string>                                        
#include <set>                                         
#include <vector>                                        
#include <algorithm>                                    
using std::string;
int main()
{
    
    string file_in {"/home/lyy/OpenCV3/STL/流迭代器/file.txt"};
    std::ifstream in {file_in};
    if(!in)
    {
        std::cerr << file_in << " not open." << std::endl;
        exit(1);
    }
    //set 容器会以升序保存单词,并且这个容器中的每个单词都有自己的 key
    std::set<string> dictionary {std::istream_iterator<string>(in), std::istream_iterator<string>()};
    std::cout << dictionary.size() << " words in dictionary." << std::endl;
    std::vector<string> words;
    string word;
    //words 容器中包含从 cin 中输入的单词的字谜。
    //每一个单词都在 while 循环的第一个 if 表达式中读取
    while(true)
    {
        std::cout << "\nEnter a word, or Ctrl+z to end: ";
        //调用流对象的 eof(),当输入 Ctrl+Z 时,eof() 会返回 true。
        if((std::cin >> word).eof()) 
            break;
        string word_copy {word};

        //
        do
        {  //对于每次排列,包括第一次,都调用 count() 来确定这个单词是否在 dictionary 容器中
            if(dictionary.count(word))  
                words.push_back(word);
            //输入的单词的字符重排列
            std::next_permutation(std::begin(word), std::end(word));
        } while(word != word_copy);//当排列返回原始单词时,do-while 循环结束

        std::copy(std::begin(words), std::end(words), std::ostream_iterator<string>{std::cout, " "});
        std::cout << std::endl;

        //如果期望每次出现 8 个字谜,需要使用循环来生成多行输出
        size_t count {}, max {8};
        for (const auto& wrd : words)
            std::cout << wrd << ((++count % max == 0) ? '\n' : ' ');

        words.clear();                                            
        
    }
    in.close();                                                 
    
}

结果显示:

4.2文件输出
代码语言:javascript
复制
    #include <iostream>                                      
    #include <fstream>                                       
    #include <iterator>                                      
    #include <string>                                        
    using std::string;
    int main()
    {   
        //从输入文件复制单词到输出文件,以空格隔开输出的单词。这个程序总会覆盖输出文件的内容
        string file_in {"/home/lyy/OpenCV3/STL/流迭代器/file.txt"};
        std::ifstream in {file_in};
        if(!in)
        {
            std::cerr << file_in << " not open." << std::endl;
            exit(1);
        }
        string file_out {"/home/lyy/OpenCV3/STL/流迭代器/file_copy.txt"};
        std::ofstream out {file_out};


        //为了确保能够用流迭代器准确地复制原文件,必须一个字符一个字符地读文件,并阻止 >> 运算符忽略空格
        std::copy(std::istream_iterator<char>{in >> std::noskipws},
                    std::istream_iterator<char>{},std::ostream_iterator<char> {out});
        in.clear();                                            
        std::cout << "Original file length: " << in.tellg() << std::endl;
        std::cout << "File copy length: " << out.tellp() << std::endl;
        in.close();
        out.close();
    }

结果显示:

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-03-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码出名企路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 2.输出流
  • 3.重载插入和提取运算符
  • 4.文件流
    • 4.1文件输入
      • 4.2文件输出
      相关产品与服务
      容器服务
      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档