当前位置:   article > 正文

C++读文件很难么?std::copy的骚操作(实用的用法)!_std::copy vector

std::copy vector

欢迎关注我的微信公众号:MatlabGUI QtCPP等学习记录

Contents

  • Contents

  • std::copy 简介

  • 使用std::copy把文件中的内容放入vector中

    • case1:把文件中的单词直接放到一个vector中

    • case2:把文件中的数值放到一个vector中

  • 使用std::copy把cin中的东西直接放到vector中

  • 使用std::copy把vector中的值直接打印出来(输出到std::cout)

  • 使用std::copy直接打印出文件中的内容

std::copy 简介

函数原型:

  1. template<class InputIterator, class OutputIterator>
  2.   OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result)
  3. {
  4.   while (first!=last) {
  5.     *result = *first;
  6.     ++result; ++first;
  7.   }
  8.   return result;
  9. }

上面这是标准库里写的,可见其形式参数是两个输入迭代器和一个输出迭代器!这两个输入迭代器决定了我们要拷贝的范围,那个输出迭代器明确了我们要拷贝到哪里去!

但是有一点需要注意:我们需要保证目的容器的空间足够大以至于能放下拷贝过来的内容。如果你的目的容器是一个空的容器,那么可以使用back_inserter(container)来创建一个插入迭代器作为输出迭代器!

使用std::copy把文件中的内容放入vector中

case1:把文件中的单词直接放到一个vector中

这个功能有的时候也算是比较常用的吧,做一些统计之类的操作。比如我要把像下图中的这个文本中的所有单词放到一个vector中。

先上代码后解释

  1. std::vector<std::string> words;
  2. std::ifstream in_file("words.txt");
  3. std::copy(std::istream_iterator<std::string>(in_file),std::istream_iterator<std::string>(),std::back_inserter(words));

就这三行就能把文本中所有以空格分开的字符串都放到一个vector中如下:

传统的方式是用一个while循环来做的,一次读一行,对这一行的字符串按空白进行分割。这听起来就感觉挺麻烦的(所以我就不写代码了),肯定没有这种函数式的风格简洁。

上述代码需要如下的头文件

  1. #include<fstream>       // for ifstream
  2. #include<iterator>      // for istream_iterator and back_inserter
  3. #include<algorithm>     // for copy
  4. #include<vector>
  5. #include<string>
  1. std::ifstream in_file("words.txt");
  2. 这个式用来创建一个(读)文件流,用于初始化后面的输入迭代器
  1. copy 的第一个参数:
  2. std::istream_iterator<std::string>(in_file),
  3. istream_iterator是一个输入流的迭代器;
  4. 它有一个模板参数,用于表示迭代器指向的类型;
  5. 我们这里是让迭代器指向文件中的一个单词,也就是一个string
  6. 所以这个模板参数设置为std::string
  7. 它接收一个参数表示是哪个流的迭代器,很明显这里应该是文件流的迭代器。
  1. copy的第二个参数:
  2. std::istream_iterator<std::string>()
  3. 这是一个尾后迭代器,不接收参数就表示一个尾后迭代器!
  1. copy的第三个参数:
  2. std::back_inserter(words);
  3. 这个back_inserter用来创建一个插入迭代器;
  4. 它接收一个容器对象作为参数;
  5. 实际上是在不断地调用这个容器的: push_back()方法;(前提是这个容器有push_back方法)

case2:把文件中的数值放到一个vector中

这个应用场景也挺多的,就拿我这专业上的例子来说:我通过采集信号的设备,采集信号,然后保存到文件里,方便后续的分析。那么我们读这个保存信号的文件也就能用这个方法!

如下图,我创建了一个存了若干个double的文件,我还是用三行代码把它放到一个vector中。代码和上面的代码几乎一样,只不过把模板参数类型由string换成double

代码和上面一样,就不解释了,把string换成double就行

  1. std::vector<double> sig;
  2.     std::ifstream in_file("signals.txt");
  3.     std::copy(std::istream_iterator<double>(in_file),std::istream_iterator<double>(),std::back_inserter(sig));
 

观察结果发现,其实这样做还是有点误差的,但是还是可以忽略不计的,差了10的-14次方。

使用std::copy把cin中的东西直接放到vector中

这个这两天我用的比较多,最近一直在找工作,参加了一些公司的笔试,考算法题,这些算法题的输入都是从std::cin中获取。

如果是从命令行中输入单个变量的值就直接像下面这样就好:

  1. int a;
  2. std::cin >> a;

但是,如果,我要一下子输入多个相同类型的值呢?比如输入多个数字到一个vector中,传统的方法还是用while循环来干。但是你用std::copy的话,一行就行(除了定义变量)。

  1. std::vector<int> nums;
  2. std::copy(std::istream_iterator<int>(std::cin),std::istream_iterator<int>(),std::back_inserter(nums));
 

使用std::copy把vector中的值直接打印出来(输出到std::cout)

  1. std::vector<int> vec{12345};
  2. std::copy(vec.begin(), vec.end(), std::ostream_iterator<int>(std::cout, "\t\t"));
 

  1. 这里std::copy的第三个参数:
  2. std::ostream_iterator<int>(std::cout, "\t\t")
  3. 和前面的的istream_iterator不同的是,这里它还能制定一个分隔符;
  4. 这里以两个制表符来分隔vector中的每个元素。

使用std::copy直接打印出文件中的内容

  1. std::ifstream in_file("words.txt");
  2. std::copy(std::istream_iterator<std::string>(in_file),
  3.           std::istream_iterator<std::string>(),
  4.           std::ostream_iterator<std::string>(std::cout, " ")
  5.         );

这个copy这块原本是一行的,但是太长了,就分开了。反正就是一个内置的算法函数。

怎么样?反正比  用while循环读  方便吧。


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/707801
推荐阅读
相关标签
  

闽ICP备14008679号