3

这里有一个精神上非常相似的问题。不幸的是,这个问题没有引起太多的回应——我想我会问一个更具体的问题,希望可以提出一种替代方法。

我正在将二进制文件写入std::cin(使用tar --to-command=./myprog)。二进制文件恰好是一组浮点数,我想将数据放入std::vector<float>- 理想情况下是 c++ 方式。

std::vector<char>我可以很好地 生成一个(感谢这个答案

#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
}

我现在想将 mystd::vector<char>转换为 a std::vector<float>,大概是 withstd::transform和一个进行转换的函数(例如 achar[2]到 a float)。然而,我正在苦苦挣扎,因为我std::vector<float>的元素将是std::vector<char>. 如果我可以以 2 的步幅进行迭代,那么我想我会很好,但从前面的问题来看,我似乎不能这样做(至少不能优雅地)。

4

3 回答 3

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));
}
于 2011-03-24T19:13:11.220 回答
0

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

于 2011-03-24T19:03:24.103 回答
0

使用升压范围适配器:

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

您可能需要自己编写istreambuf_iterator,这很简单

于 2014-07-10T09:56:00.247 回答