2011-03-24 42 views
3

在精神here中有一个非常相似的问题。不幸的是,这个问题没有引起太多的回应 - 我想我会问一个更具体的问题,希望能够提出一种替代方法。如何迭代到更小的容器中(即步幅!= 1)

我正在写一个二进制文件到std::cin(与tar --to-command=./myprog)。 二进制文件碰巧是一组浮点数,我想将数据放入std::vector<float> - 理想情况下是C++的方式。

我可以生成一个std::vector<char>非常漂亮(感谢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 
} 

我现在想我std::vector<char>std::transform并执行转换(一个char[2]float功能转变成一个std::vector<float>,想必,说)。然而,我挣扎着,因为我的std::vector<float>将有std::vector<char>元素的一半。如果我可以迭代2次,那么我认为我会好起来的,但从前面的问题看来,我不能那样做(至少不是那么优雅)。

+1

为什么要读'char'?为什么不'std :: string'的?目前还不清楚你想要输入什么,以及你想要完成什么。 – GManNickG 2011-03-24 19:01:19

+0

@GMan,我想完成一个std :: vector 从一个二进制文件输入到cin中 - 然后我可以使用库函数来解码std :: vector。如果通过叮咬进行治疗更容易,那很好(我不清楚如何用cin做到这一点)。 – Tom 2011-03-24 19:06:06

+0

@Tom:二进制文件的格式是什么? – GManNickG 2011-03-24 19:07:47

回答

5

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

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]; 
}; 

通过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; 
}; 

然后使用它是这样的:

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)); 
} 
+0

+1。为了完成他的回答,根据他的问题的评论,它应该读取'sizeof(float)''char'然后'reinterpret_cast'到'float',假设字节顺序不是问题。 (如果是的话,换一些'char'左右。) – GManNickG 2011-03-24 19:16:31

+0

啊,很酷,这看起来正是我要找的东西 - 让我试着去解决它 – Tom 2011-03-24 19:22:15

+0

谢谢@Martin,比你@Gman,我离开它给你的想象力,你刚刚取代了c和C++的可怕的混杂:) – Tom 2011-03-24 19:29:09

0

在我看来,最好的答案是编写一对你自己的迭代器,以你想要的方式解析文件。您可以将std::vector<char>更改为std::vector<float>并使用相同的streambuf迭代器,前提是输入的格式化值至少有一个空格。

0

使用升压范围适配器:

boost::copy(istream_range(input)|stride(2),back_inserter(buffer)); 

你可能需要写你自己的istreambuf_iterator,这个h是trivial