将unsigned char转换为unsigned short(big endian)

时间:2018-01-26 14:51:33

标签: c++ type-conversion

我有一个LabVIEW程序(不是我的),它将数据(uint16)保存在二进制文件中,如下所示: enter image description here

  • 将数字拆分2 ^ 8得到2 uint8(例如320 = 256 + 64)
  • 在保存前切换数据(所以此处以64开头,以256结束)

这就是为什么我读4个八位字节来得到2个无符号短

ifstream is("filename", ifstream::binary);
if (is) {
    is.seekg(0, is.end);

    unsigned char data_char[4];
    unsigned short data;

    is.seekg(376, is.beg);
    is.read(reinterpret_cast<char*>(width), sizeof(width));

    // What I tried (switch and convert)
    data = data_char[1]<<24 + data_char[0]<<16 + data_char[3]<<8 + data_char[2];
}

例如,值320(uint8)保存在文件中,当我读取data_char时,我有一个带有4个组合数的unsigned char:

  • [0] = 0'\ 0'
  • [1] = 64'@'
  • [2] = 1'\ x1'
  • [3] = 0'\ 0'

我有256个人:

  • [0] = 1'\ x1'
  • [1] = 0'\ 0'
  • [2] = 0'\ 0'
  • [3] = 0'\ 0' [0]和[1]是第一个uint8,[2]和[3]是第二个。

但是,作为C ++的新手,我尝试了一点转换将char转换为short,但我没有做正确的方法。

我知道你这很容易,但是你能帮我吗?

有关信息,在Python中我只需要执行:sum(struct.unpack(">HH", f.read(4))

2 个答案:

答案 0 :(得分:2)

要将big endian转换为native endian,只需将字节的位宽乘以字节位置的差值和整数的大小,并按位或组合所有内容。

更具体地说:第一个字节移位最显着,最后一个字节根本没有移位。

template<class T>
T my_ntoh(unsigned char* buf) {
    const auto s = sizeof(T);
    T value = 0;
    for (unsigned i = 0; i < s; i++)
        value |= buf[i] << CHAR_BIT * (s - 1 - i);
    return value;
}

此模板适用于任何大小的整数,读取的字节数与整数类型的大小相同。

如果您可以依赖POSIX,它会提供ntohs,因此您不必自己编写此转换。

因为你想要阅读两个大的无符号短符并将它们加在一起(我使用uint16_t,因为它保证是2个八位字节):

auto part1 = my_ntoh<uint16_t>(data_char);
auto part2 = my_ntoh<uint16_t>(data_char + sizeof part1);
data = part1 + part2;

答案 1 :(得分:1)

您应该使用特殊的标准函数来执行此操作。看一下htons()ntohs()(主机到网络和网络到主机的短路)。在线查找文档(特定于您的系统)没有问题,这里有一个这样的页面:http://beej.us/guide/bgnet/html/multi/htonsman.html