将vector <unsigned char =“”>转换为vector <unsigned short =“”> </unsigned> </unsigned>

时间:2009-12-13 23:34:05

标签: c++

我从二进制文件中获取数据,从文件中读取并在unsigned char的向量中写入。我无法编辑它,因为我正在使用外部库。

但我从文件中读取的数据是16位图像,我想将数据放入无符号短矢量

也许我可以为它做演员表?

RGDS。

5 个答案:

答案 0 :(得分:6)

通用方法(非防弹):

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

typedef unsigned char u8;
typedef unsigned short u16;

u16 combine_two_bytes(u8 a, u8 b) {
    return a | (b << 8);
}

template<typename InIter, typename OutIter, typename InT, typename OutT>
void combine_pairs(InIter in, InIter in_end, OutIter out, OutT (*func)(InT, InT)) {
    while(1) {
        if(in == in_end) {
            break;
        }

        InT &left = *in++;

        if(in == in_end) {
            break;
        }

        InT &right = *in++;

        *out++ = func(left, right);
    }
}

int main() {
    using namespace std;    // lazy

    u8 input[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
    const size_t in_size = sizeof(input) / sizeof(*input);
    u16 output[in_size / 2];

    cout << "Original: ";
    copy(input, input + in_size, ostream_iterator<int>(cout, " "));
    cout << endl;

    combine_pairs(input, input + in_size, output, combine_two_bytes);

    cout << "Transformed: ";
    copy(output, output + in_size / 2, ostream_iterator<int>(cout, " "));
    cout << endl;

    return 0;
}

答案 1 :(得分:6)

如果您只想将一种类型转换为另一种类型,请使用标准构造函数。只要迭代器值类型可自动转换为目标向量值类型,编译器就会在两种类型之间进行自动转换。只需使用标准构造函数

#include <vector>
#include <algorithm>
#include <iterator>

int main()
{
    std::vector<unsigned char>      a;
    a.push_back((unsigned char)12);
    a.push_back((unsigned char)13);
    a.push_back((unsigned char)14);

    std::vector<unsigned short>     b(a.begin(),a.end());

    // Print out the vector
    std::copy(b.begin(),b.end(),std::ostream_iterator<unsigned short>(std::cout,"\t"));
}

> g++ t.cpp
> ./a.out
12  13 14

如果您确实想将两个字节转换为一个字节,则需要进行一些工作。但这取决于输入数据是否与您所使用的机器实际上具有相同的字节顺序。如果你知道它只是你需要转换输入类型的相同的endianess。

#include <vector>
#include <algorithm>
#include <iterator>

int main()
{
    std::vector<unsigned char>      a;

    // Make sure that the size is correct.
    // ie. An Odd number indicates that something is not quite correct.
    //
    std::vector<unsigned short>     b(static_cast<unsigned short*>(&a[0]),
                                      static_cast<unsigned short*>(&a[a.size()]));

    // Print out the vector
    std::copy(b.begin(),b.end(),std::ostream_iterator<unsigned short>(std::cout,"\t"));
}

或者,如果您确实需要将两个值组合成一个值,其中endianess与目标体系结构不同,则可以编写一个特殊的迭代器。像这样:

#include <Converter.h>

int main()
{
    std::vector<unsigned char>      a;

    // Make sure that the size is correct.
    // ie. An Odd number indicates that something is not quite correct.
    //
    std::vector<unsigned short>     b(make_Converter(a.begin()),make_Converter(a.end()));

    // Print out the vector
    std::copy(b.begin(),b.end(),std::ostream_iterator<unsigned short>(std::cout,"\t"));
}

Converter.h

#include <vector>
#include <iostream>
#include <iterator>

template<typename I>
struct Converter
{
    I   iterator;

    typedef typename std::input_iterator_tag                    iterator_category;
    typedef typename std::iterator_traits<I>::value_type        value_type;
    typedef typename std::iterator_traits<I>::difference_type   difference_type;
    typedef typename std::iterator_traits<I>::pointer           pointer;
    typedef typename std::iterator_traits<I>::reference         reference;

    Converter(I iter)
        :iterator(iter)
    {}

    Converter& operator++()
    {
        iterator++;
        return *this;
    }

    Converter operator++(int)
    {
        Converter   tmp(*this);
        this->operator++();

        return (tmp);
    }

    value_type operator*()
    {
        /*
         * The actual calculation done here will depend on the underlying hardware.
         */
        typename std::iterator_traits<I>::value_type val(*iterator);
        val << 8;
        iterator++;
        val |= (*iterator);

        return val;
    }

    bool operator!=(Converter const& rhs)
    {
        return iterator != rhs.iterator;
    }
};

template<typename I>
Converter<I> make_Converter(I iter)
{
    return Converter<I>(iter);
}

答案 2 :(得分:4)

vector<unsigned char> a = ...;
vector<unsigned short> b(a.begin(), a.end());

但是你希望valarray用于简单的数据向量。

答案 3 :(得分:1)

假设文件中的二进制数据是小端序,我会这么做:

vector<unsigned char> a = ...;

std::vector<unsigned short> b;
b.reserve( a.size() / sizeof(unsigned short) );

for( std::vector<unsigned char>::const_iterator i=a.begin(); i!=a.end(); i+=2 )
{
    unsigned short shortValue = *(i+1);
    shortValue <<= 8;
    shortValue |= *i;
    b.push_back( shortValue );
}

如果文件中的数据是big-endian,则需要反过来组合短值。您还应该防止“a”中的条目数不是2的倍数。

答案 4 :(得分:0)

免责声明:我现在没有编译器:

vector<unsigned char> vec = getVector();
vector<unsigned short> sv(reinterpret_cast<unsigned short*>(&vec[0]), 
                          reinterpret_cast<unsigned short*>(&vec[vec.size()]));
相关问题