C++ 转换向量<;无符号字符>;到向量<;未签名短消息>;

C++ 转换向量<;无符号字符>;到向量<;未签名短消息>;,c++,C++,我从一个二进制文件中获取数据,从文件中读取数据,然后写入一个无符号字符向量。我无法编辑它,因为我正在使用外部库 但我从文件中读取的数据是一个16位的图像,我想把数据放在一个无符号的短向量中 也许我可以为它做一个演员 Rgds.向量a=。。。; 向量b(a.begin(),a.end()); 但是对于简单的数据向量,您需要valarrays。通用方法(非防弹): #包括 #包括 #包括 #包括 typedef无符号字符u8; typedef无符号短u16; u16合并两个字节(u8 a、u8 b

我从一个二进制文件中获取数据,从文件中读取数据,然后写入一个无符号字符向量。我无法编辑它,因为我正在使用外部库

但我从文件中读取的数据是一个16位的图像,我想把数据放在一个无符号的短向量中

也许我可以为它做一个演员

Rgds.

向量a=。。。;
向量b(a.begin(),a.end());
但是对于简单的数据向量,您需要
valarray
s。

通用方法(非防弹):

#包括
#包括
#包括
#包括
typedef无符号字符u8;
typedef无符号短u16;
u16合并两个字节(u8 a、u8 b){

返回a |(b假设文件中的二进制数据是以小尾端顺序排列的,我将用简单的方法执行此操作:

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 );
}
向量a=。。。; std::载体b; b、 保留(a.size()/sizeof(无符号短); 对于(std::vector::const_迭代器i=a.begin();i!=a.end();i+=2) { 无符号短值=*(i+1);
shortValue免责声明:我现在没有编译器:

vector<unsigned char> vec = getVector();
vector<unsigned short> sv(reinterpret_cast<unsigned short*>(&vec[0]), 
                          reinterpret_cast<unsigned short*>(&vec[vec.size()]));
vector-vec=getVector();
向量sv(重新解释和向量[0]),
重新解释投射(&vec[vec.size()]);

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

#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
#包括
#包括
#包括
int main()
{
std::载体a;
a、 推回((无符号字符)12);
a、 推回((无符号字符)13);
a、 推回((无符号字符)14);
向量b(a.begin(),a.end());
//打印出向量
std::copy(b.begin()、b.end()、std::ostream_迭代器(std::cout,“\t”);
}
>g++t.cpp
>/a.out
12  13 14
如果您确实想将两个字节转换为一个字节,则需要进行一些工作。但这取决于输入数据是否与您所在的计算机的尾数相同。如果您知道尾数相同,则只需转换输入类型即可

#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"));
}
#包括
#包括
#包括
int main()
{
std::载体a;
//确保尺寸正确。
//奇数表示某事不太正确。
//
std::向量b(静态_转换(&a[0]),
静态投影(&a[a.size()]);
//打印出向量
std::copy(b.begin()、b.end()、std::ostream_迭代器(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"));
}
#包括
int main()
{
std::载体a;
//确保尺寸正确。
//奇数表示某事不太正确。
//
向量b(make_转换器(a.begin()),make_转换器(a.end());
//打印出向量
std::copy(b.begin()、b.end()、std::ostream_迭代器(std::cout,“\t”);
}
转炉

#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);
}
#包括
#包括
#包括
模板
结构转换器
{
I迭代器;
typedef typename std::input_iterator_tag iterator_category;
typedef typename std::迭代器特征::值类型值类型;
typedef typename std::迭代器特征::差异类型差异类型;
typedef typename std::迭代器_traits::指针;
typedef typename std::iterator_traits::reference;
转换器(iter)
:迭代器(iter)
{}
转换器和运算符++()
{
迭代器++;
归还*这个;
}
转换器运算符++(int)
{
转换器tmp(*此);
这个->操作符++();
返回(tmp);
}
值类型运算符*()
{
/*
*此处进行的实际计算将取决于底层硬件。
*/
typename std::iterator\u traits::value\u type val(*iterator);

所以你想把
[a,b,c,d]
变成
[ba,dc]
?也许这篇文章可以让你知道该怎么做:我不知道他是想让n个无符号字符的向量变成n个无符号短字符的向量,还是n/2个无符号短字符的向量。看起来,如果他想要n/2个元素,他假设无符号短字符是2个字节。但上面提到的问题还不清楚。不需要进行强制转换。向量hav一个包含两个迭代器的构造函数。只要迭代器的值类型可转换为目标容器的值类型,编译器就会做正确的事情。@Martin York:除了他不想将
char
s转换为
short
s之外,他希望将它们重新解释为short.@rlbond:这是有争议的。它是epends你是如何理解这个问题的。因为这个问题下的评论,它是倾斜的。事实上没有争论:数据代表“一个16位的图像”,即返回每个单词的唯一方法是组合2个字节。将每个字节扩大到16位没有帮助。非常好。一个次要的批评是,由于for循环中的语句“i+=2”,您的代码仅限于随机访问容器。如果您将其更改为“std::advance(i,2)”,它将适用于所有容器(对于随机访问迭代器,时间将继续保持不变)@Klatchko,谢谢你的评论。你是对的,代码仅限于随机访问迭代器。但是,即使使用
std::advance
我也检查了
I+1
,这不能用所有容器来完成。我已经重新编写了代码,希望它现在工作得更好(并且更安全)。
#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"));
}
#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);
}