читать байтовое 16-битное целое число без знака

Я смотрю в разборе TERMINFO файлы базы данных, которые являются типом двоичных файлов. Вы можете прочитать о его формат хранения и подтвердите проблему, с которой я столкнулся.

Руководство говорит —

Заголовок раздела начинается с файла. Этот раздел содержит
шесть коротких целых чисел в формате, описанном ниже. Эти
целые числа

(1) магическое число (восьмеричное 0432);

Короткие целые числа хранятся в двух 8-битных байтах. Первый
байт содержит младшие 8 битов значения,
и второй байт содержит старшие 8 бит.
(Таким образом, представленное значение равно 256 * second + first.)
значение -1 представлено двумя байтами 0377, 0377; Другой
отрицательные значения незаконны
. Это значение обычно означает
что соответствующая возможность отсутствует в этом
Терминал. Машины, где это не соответствует
аппаратное обеспечение должно прочитать целые числа как два байта и вычислить
значение с прямым порядком байтов
.


  • Первая проблема при синтаксическом анализе этого типа входных данных заключается в том, что он фиксирует размер до 8 бит, поэтому нельзя использовать обычный старый символ, поскольку он не гарантирует, что размер будет ровно 8 бит. Так я смотрюЦелочисленные типы фиксированной шириныно опять столкнулся с дилеммой выбора ч / б int8_t или же uint8_t в котором четко говорится — «предоставляется только в том случае, если реализация напрямую поддерживает тип». Так что я должен выбрать, чтобы тип был достаточно портативным.

  • Вторая проблема — нет buffer.readInt16LE() метод в стандартной библиотеке c ++, который может читать 16 байтов данных в формате Little Endian. Так как же мне продолжить, чтобы снова реализовать эту функцию в портативном & безопасный способ.

Я уже пытался читать это с 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',
....
....

3

Решение

Первая проблема при синтаксическом анализе этого типа входных данных заключается в том, что он фиксирует размер до 8 бит, поэтому нельзя использовать обычный старый символ, поскольку он не гарантирует, что размер будет ровно 8 бит.

Любое целое число, которое по крайней мере 8 бит, в порядке. В то время как char не гарантируется, что он будет точно 8 битами, он должен быть не менее 8 битов, поэтому с точки зрения размера, нет никаких проблем, кроме того, что в некоторых случаях вам может понадобиться маскировать старшие биты, если они существуют. Тем не мение, char может не быть без знака, и вы не хотите, чтобы октеты интерпретировались как подписанные значения, поэтому используйте unsigned char вместо.

Вторая проблема заключается в том, что в стандартной библиотеке c ++ отсутствует метод buffer.readInt16LE (), который мог бы считывать 16 байтов данных в формате Little Endian. Так как же мне продолжить, чтобы снова реализовать эту функцию в портативном & безопасный способ.

Читайте один октет за раз в unsigned char, Присвойте первый октет переменной (достаточно большой, чтобы представить не менее 16 бит). Сдвиньте биты второго октета влево на 8 и присвойте переменной, используя битовое соединение или.

Или, что еще лучше, не используйте его заново, а используйте стороннюю библиотеку.

Я уже пробовал читать это с типом данных char, но это определенно производит мусор на моей машине.

Тогда ваша попытка была ошибочной. Нет проблем, присущих char это приведет к выводу мусора. Я рекомендую использовать отладчик для решения этой проблемы.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]