如何迭代到更小的容器(即stride!= 1) [英] how to iterate into a smaller container (i.e. 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屋!