Как преобразовать и объединить позиции в lpBuffer, чтобы получить шестнадцатеричное число, напечатанное как целое число? - PullRequest
0 голосов
/ 29 августа 2018

Я новичок в C ++.

Я ссылался на более 10 страниц stackoverflow, ссылаясь на схожие проблемы, но, что бы я ни пытался, я не могу экстраполировать решение, соответствующее моей конкретной проблеме.

У меня есть некоторая электроника, подающая данные в последовательный порт, правильность которых проверяется с помощью RealTerm и XCTU. (Короче говоря, я знаю, что данные, отправляемые в порт, верны)

Я получаю доступ к последовательному порту, используя CreateFile () / dcb. (Код настройки порта, который я уверен, является правильным, но если вы хотите увидеть код, чтобы убедиться, что вы сами дайте мне знать) (Если доступ к последовательному порту другим способом решит эту проблему, дайте мне знать)

Единственное действие, которое я выполняю с портом, - это ReadFile (). LpBuffer, используемый вызовом ReadFile (), настроен как char []. Я не знаю почему, но кажется, что каждый индекс char [] принимает только один байт информации. В целях отладки я использую:

cout << hex << setfill('0') << setw(2) ...

Чтобы он выводился на консоль следующим образом:

lpBuffer in [...] = ...
lpBuffer in [11] = 03
lpBuffer in [12] = ff
lpBuffer in [...] = ...

Я хотел бы использовать концепцию объединения двух строк, чтобы получить:

03ff (1023)

Я бы также предпочел ответ, в котором «конкатенированное» значение хранится в переменной, без изменения информации, хранящейся в lpBuffer / char [] (буквально не конкатенируя ее), и сохраняет значение в виде целого числа.

Я пытался использовать sprintf_s (), stringstream, преобразовать в строку и использовать stoi. Самые близкие ответы, которые я нашел, похоже, не работают для lpBuffers (char [], хранящих байтовые данные в отличие от реальных символов?), А также преобразуют все индексы массива, а не только конкретные.

Пожалуйста, помогите, C ++ Wizards!

1 Ответ

0 голосов
/ 30 августа 2018

Хотя некоторые вещи об этом немного уродливы, вы обычно хотите определить структуру, которая описывает данные так, как вы ожидаете. Например, предположим, что ваши данные - это два длинных (4-байтовых элемента), за которыми следуют два коротких (2-байтовых элемента).

#pragma pack(1);
struct my_input {
    long data1;
    long data2;
    short data3;
    short data4;
    // more stuff here
};

Затем, когда вы читаете в буфере, полном данных, вы можете привести что-то вроде этого:

my_input *in = (my_input *)&buffer[0];

Затем вы можете посмотреть на данные через объектив этой структуры (так сказать) и увидеть типы, которые должны быть там:

std::cout << in->data4;

В данном конкретном случае у вас есть еще один незначительный поворот: хотя данные, которые вы получаете, находятся в порядке с прямым порядком байтов или (как его иногда называют) сетевым порядком. К счастью, обычная сетевая библиотека предоставляет несколько функций для преобразования данных сетевого порядка в данные, используемые процессором, для которого вы его компилируете, поэтому (в данном случае) вам нужно что-то вроде этого:

std::cout << ntohs(in->data4);

Есть ntohs для «коротких» (16-битных) значений, а также ntohl для длинных (32-битных) и (в большинстве современных сетевых стеков) ntohll для длинных и длинных (64-битных) значения.

Обратите внимание на pragma pack(1). Он говорит компилятору не вставлять дополнительные поля между полями. Когда вы пытаетесь сопоставить внешне определенную структуру, если там есть какие-либо отступы, вы, как правило, хотите вставлять ее явно, вместо того, чтобы полагать, что компилятор вставит ее туда, куда вы хотите.

...