读小端16位无符号整数

时间:2016-12-24 19:52:07

标签: c++ linux c++11 terminal terminfo

我正在研究解析terminfo数据库文件,这是一种二进制文件。您可以自己阅读storage format,并确认我面临的问题。

手册说 -

  

标题部分开始文件。本节包含     下面描述的格式的六个短整数。这些     整数是

     

(1)幻数(八进制0432);

     

...

     

...

     

短整数存储在两个8位字节中。首先      byte包含值的最低有效8位,      第二个字节包含最重要的8位。      (因此,表示的值是256 *秒+第一个。)      值-1由两个字节0377,0377表示;其他      负值是非法的。这个值通常意味着      从而缺少相应的功能      终奌站。 与此不符的机器      硬件必须将整数读取为两个字节并进行计算      小端值

  • 解析这种类型的输入时的第一个问题是它将大小固定为8位,因此不能使用普通的旧字符,因为它不能保证大小正好是8位。所以我在寻找Fixed width integer types'但是再次遇到了选择b / w int8_tuint8_t明确说明的问题 - "只有在实施直接支持类型"时才提供。那么我应该选择什么才能使类型足够便携。

  • 第二个问题是c ++标准库中没有buffer.readInt16LE()方法,它可能以Little Endian格式读取16个字节的数据。那么我该如何继续在便携式设备中再次实现这个功能呢?安全的方式。

我已经尝试用char数据类型读取它,但它肯定会在我的机器上产生垃圾。 infocmp命令可以读取正确的输入,例如 - $ infocmp xterm

#include <fstream>
#include <iostream>
#include <vector>

int main()
{
    std::ifstream db(
      "/usr/share/terminfo/g/gnome", std::ios::binary | std::ios::ate);

    std::vector<unsigned char> buffer;

    if (db) {
        auto size = db.tellg();
        buffer.resize(size);
        db.seekg(0, std::ios::beg);
        db.read(reinterpret_cast<char*>(&buffer.front()), size);
    }
    std::cout << "\n";
}
$1 = std::vector of length 3069, capacity 3069 = {26 '\032', 1 '\001', 21 '\025',
  0 '\000', 38 '&', 0 '\000', 16 '\020', 0 '\000', 157 '\235', 1 '\001',
  193 '\301', 4 '\004', 103 'g', 110 'n', 111 'o', 109 'm', 101 'e', 124 '|',
  71 'G', 78 'N', 79 'O', 77 'M', 69 'E', 32 ' ', 84 'T', 101 'e', 114 'r',
  109 'm', 105 'i', 110 'n', 97 'a', 108 'l', 0 '\000', 0 '\000', 1 '\001',
  0 '\000', 0 '\000', 1 '\001', 0 '\000', 0 '\000', 0 '\000', 0 '\000',
  0 '\000', 0 '\000', 0 '\000', 0 '\000', 1 '\001', 1 '\001', 0 '\000',
....
....

1 个答案:

答案 0 :(得分:2)

  

解析这种类型的输入时的第一个问题是它将大小固定为8位,因此不能使用普通的旧字符,因为它不能保证大小正好是8位。

任何至少8位的整数都可以。虽然char不能保证恰好是8位,但要求至少为8位,因此就尺寸而言,除了在某些情况下需要屏蔽之外没有问题高位如果存在的话。但是,char可能不是未签名的,并且您不希望将八位字节解释为有符号值,因此请改用unsigned char

  

第二个问题是c ++标准库中没有buffer.readInt16LE()方法,它可能以Little Endian格式读取16个字节的数据。那么我该如何继续在便携式设备中再次实现这个功能呢?安全的方式。

一次读一个八位字节到unsigned char。将第一个八位字节分配给变量(足够大以表示至少16位)。将第二个八位字节的位移8,并使用复位按位或。

分配给变量

或者更好的是,不要重新实施它,而是使用第三方现有的库。

  

我已经尝试过使用char数据类型读它,但它肯定会在我的机器上产生垃圾。

然后你的尝试是错误的。 char固有的问题不会导致垃圾输出。我建议使用调试器来解决这个问题。