我正在研究解析terminfo数据库文件,这是一种二进制文件类型。您可以自己阅读有关存储格式的内容并确认我面临的问题。
手册上说-部分开始文件。此部分包含以下格式的六个短整数。这些整数是:
手册上说-
(1) 魔术数字(八进制0432);
...
...
短整数存储在两个8位字节中。第一个字节包含值的最低有效8位,第二个字节包含最高有效8位。(因此,表示的值为256*second+first)。值-1由两个字节0377, 0377表示;其他负值是非法的。这个值通常意味着此终端缺少相应的功能。 这与硬件不对应的机器必须将整数读取为两个字节并计算小端值。
解析这种类型的输入时,第一个问题是它将大小固定为8位,因此无法使用普通的char,因为它不能保证大小恰好为8位。所以我看了一下 '固定宽度整数类型' 但又面临着选择int8_t或uint8_t之间的困境,它明确说明 - "仅在实现直接支持该类型时提供"。那么我应该选择什么样的类型才能够足够便携呢。
第二个问题是,在c++标准库中没有
buffer.readInt16LE()
方法,该方法可以读取小端格式的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',
....
....
CHAR_BIT==8
。char
无法工作,那么你的代码就是有问题的。 - Carey Gregory