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

欢迎关注我的微信公众号: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 简介

函数原型:

template<class InputIterator, class OutputIterator>
  OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result)
{
  while (first!=last) {
    *result = *first;
    ++result; ++first;
  }
  return result;
}

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

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

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

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

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

先上代码后解释

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

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

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

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

#include<fstream>       // for ifstream
#include<iterator>      // for istream_iterator and back_inserter
#include<algorithm>     // for copy
#include<vector>
#include<string>
std::ifstream in_file("words.txt");
这个式用来创建一个(读)文件流,用于初始化后面的输入迭代器
copy 的第一个参数:
std::istream_iterator<std::string>(in_file),

istream_iterator是一个输入流的迭代器;
它有一个模板参数,用于表示迭代器指向的类型;
我们这里是让迭代器指向文件中的一个单词,也就是一个string;
所以这个模板参数设置为std::string。

它接收一个参数表示是哪个流的迭代器,很明显这里应该是文件流的迭代器。
copy的第二个参数:
std::istream_iterator<std::string>()
这是一个尾后迭代器,不接收参数就表示一个尾后迭代器!
copy的第三个参数:
std::back_inserter(words);

这个back_inserter用来创建一个插入迭代器;
它接收一个容器对象作为参数;
实际上是在不断地调用这个容器的: push_back()方法;(前提是这个容器有push_back方法)

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

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

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

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

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

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

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

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

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

int a;
std::cin >> a;

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

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

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

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

这里std::copy的第三个参数:
std::ostream_iterator<int>(std::cout, "\t\t")

和前面的的istream_iterator不同的是,这里它还能制定一个分隔符;
这里以两个制表符来分隔vector中的每个元素。

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

std::ifstream in_file("words.txt");
std::copy(std::istream_iterator<std::string>(in_file),
          std::istream_iterator<std::string>(),
          std::ostream_iterator<std::string>(std::cout, " ")
        );

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

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


  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值