如何迭代到更小的容器(即stride!= 1) [英] how to iterate into a smaller container (i.e. stride != 1)

查看:119
本文介绍了如何迭代到更小的容器(即stride!= 1)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个问题在精神上非常相似,这里。不幸的是,这个问题没有提供太多的反应 - 我想我会问一个更具体的问题,希望可以建议一种替代方法。



我在写一个二进制文件导入 std :: cin tar --to-command =。/ myprog )。
二进制文件恰好是一组浮点数,我想将数据放入 std :: vector< float> - 理想的是c ++方式。 p>

我可以非常好地生成 std :: vector< char> (感谢此答案

  #include< fstream> 
#include< iostream>
#include #include< algorithm>
#include< vector>

int
main(int ac,char ** av)
{
std :: istream& input = std :: cin;
std :: vector< char>缓冲;
std :: copy(
std :: istreambuf_iterator< char>(input),
std :: istreambuf_iterator< char>(),
std :: back_inserter ; //将所有数据复制到缓冲区
}



现在我要转换我的 std :: vector< char> 到 std :: vector< float> :transform 和执行转换的函数( char [2] float ,说)。然而,我努力,因为我的 std :: vector< float> 将有一半的元素 std :: vector< char> 。如果我可以迭代2步,那么我想我会很好,但从上一个问题,似乎我不能这样做(至少不优雅)。

解决方案

我会写我自己的类读取两个字符并将其转换为float。

  struct FloatConverter 
{
//当FloatConverter对象被分配给一个浮动值
//当放入向量< float>这个方法将被调用
//将对象转换为float。
operator float(){return 1.0; / *如何转换2个字符* /}

friend std :: istream&操作符>>(std :: istream& st,FloatConverter& fc)
{
//你不完全清楚什么应该读入。
//所以我去了确保我们只读了2个字符。
fc.data [0] = str.get();
fc.data [1] = str.get();
retun str
}
char data [2];
};

根据GMan的意见:

  struct FloatConverterFromBinary 
{
//当FloatConverterFromBinary对象赋给一个浮动值
//当放入向量< float>这个方法将被调用
//将对象转换为float。
operator float(){return data}

friend std :: istream&操作符>>(std :: istream& st,FloatConverterFromBinary& fc)
{
//使用reinterpret_cast强调这是多么危险和不可移植。
str.read(reinterpret_cast< char *>(& fc.data),sizeof(float));
retun str
}

float data;
};

然后使用它:

  int main(int ac,char ** av)
{
std :: istream& input = std :: cin;
std :: vector< float>缓冲;

//注意:因为FloatConverter在读取
时不会删除空格//可以使用std :: istream_iterator<>
//
std :: copy(
std :: istreambuf_iterator< FloatConverter>(input),
std :: istreambuf_iterator< FloatConverter>(),
std: :back_inserter(buffer));
}


There is a question that is very similar in spirit here. Unfortunately that question didn't prompt much response - I thought I would ask a more specific question with the hope that an alternative method can be suggested.

I'm writing a binary file into std::cin (with tar --to-command=./myprog). The binary file happens to be a set of floats and I want to put the data into std::vector<float> - ideally the c++ way.

I can generate a std::vector<char> very nicely (thanks to this answer)

#include <fstream>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>

int
main  (int ac, char **av)
{
  std::istream& input = std::cin;
  std::vector<char> buffer;
  std::copy( 
        std::istreambuf_iterator<char>(input), 
           std::istreambuf_iterator<char>( ),
           std::back_inserter(buffer)); // copies all data into buffer
}

I now want to transform my std::vector<char> into a std::vector<float>, presumably with std::transform and a function that does the conversion (a char[2] to a float, say). I am struggling however, because my std::vector<float> will have half as many elements as std::vector<char>. If I could iterate with a stride of 2 then I think I would be fine, but from the previous question it seems that I cannot do that (at least not elegantly).

解决方案

I would write my own class that reads two chars and converts it to float.

struct FloatConverter
{
    // When the FloatConverter object is assigned to a float value
    // i.e. When put into the vector<float> this method will be called
    //      to convert the object into a float.
    operator float() { return 1.0; /* How you convert the 2 chars */ }

    friend std::istream& operator>>(std::istream& st, FloatConverter& fc)
    {
        // You were not exactly clear on what should be read in.
        // So I went pedantic and made sure we just read 2 characters.
        fc.data[0] = str.get();
        fc.data[1] = str.get();
        retun str;
    }
    char   data[2];
 };

Based on comments by GMan:

struct FloatConverterFromBinary
{
    // When the FloatConverterFromBinary object is assigned to a float value
    // i.e. When put into the vector<float> this method will be called
    //      to convert the object into a float.
    operator float() { return data }

    friend std::istream& operator>>(std::istream& st, FloatConverterFromBinary& fc)
    {
        // Use reinterpret_cast to emphasis how dangerous and unportable this is.
        str.read(reinterpret_cast<char*>(&fc.data), sizeof(float));
        retun str;
    }

    float  data;
};

Then use it like this:

int main  (int ac, char **av)
{
  std::istream& input = std::cin;
  std::vector<float> buffer;

  // Note: Because the FloatConverter does not drop whitespace while reading
  //       You can potentially use std::istream_iterator<>
  //
  std::copy( 
           std::istreambuf_iterator<FloatConverter>(input), 
           std::istreambuf_iterator<FloatConverter>( ),
           std::back_inserter(buffer));
}

这篇关于如何迭代到更小的容器(即stride!= 1)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆