Инициализировать структуру typedef по проблеме атрибута - PullRequest
0 голосов
/ 09 октября 2018

Я определил структуру, основанную на байтах, с размером 3 байта.(1 packageID и 2 packetSize) Я проверил размер с помощью функции sizeof, и она хорошо работает:

#pragma pack(1)

typedef struct ENVIRONMENT_STRUCT{
    unsigned char packetID[1];
    unsigned char packetSize[2];
}

Я создал переменную и зарезервированную память, например:

ENVIRONMENT_STRUCT * environment_struct = new ENVIRONMENT_STRUCT();

ПокаЯ хочу инициализировать environment_struct .

Проблема в том, что я пытаюсь инициализировать эту структуру по атрибуту, вот так:

*environment_struct->packetSize = 100;

Но когда я проверил этозначение, используя:

std::cout << "Packet Size: " << environment_struct->packetSize << endl;

Результат: Размер пакета: d

Ожидаемый результат: Размер пакета: 100

Если я буду работать с числами, я должен определить структуру, используя библиотеку csdint?Например, u_int8 и этот тип переменной.

Ответы [ 4 ]

0 голосов
/ 09 октября 2018

Давайте сначала рассмотрим, что делает *environment_struct->packetSize = 100;.Он устанавливает первый байт от ENVIRONMENT_STRUCT::packetSize до 100. Более обычный синтаксис для этого: environment_struct->packetSize[0] = 100.

На самом деле нет способа инициализировать структуру таким образом, чтобы выражение std::cout << environment_struct->packetSize получило результатна выходе 100. Давайте рассмотрим, что это делает.environment_struct->packetSize - это массив, который в этом случае распадается на указатель на первый элемент.Символьные указатели, вставленные в символьные потоки, интерпретируются как символьные строки с нулевым символом в конце.К счастью, вы инициализировали значение второго байта environment_struct->packetSize, поэтому ваш массив действительно завершен нулем.Значение первого байта интерпретируется как закодированный символ.В вашей системе кодирования случается так, что d символ закодирован как значение 100.

Если вы хотите напечатать числовое значение первого байта environment_struct->packetSize, который вы установили равным 100, вы можетеиспользование:

std::cout << "Packet Size: " << (int)environment_struct->packetSize[0] << endl;
0 голосов
/ 09 октября 2018

Вы получаете этот результат, когда пытаетесь напечатать символ символа, а не целое число.

Чтобы исправить это, просто приведите значение или объявите его как целое число в зависимости от ваших потребностей.

Пример актерского состава:

std::cout << "Packet Size: " << static_cast<int>(*environment_struct->packetSize) << std::endl;
0 голосов
/ 09 октября 2018

Когда вы делаете

ENVIRONMENT_STRUCT * environment_struct = new ENVIRONMENT_STRUCT();

, вы инициализируете packetSize как {0, 0}.Затем

*environment_struct->packetSize = 100;

превращает массив в {100, 0}.Так как массив является массивом символов, когда вы отправляете его на cout с

std::cout << "Packet Size: " << environment_struct->packetSize << endl;

, он обрабатывает его как c-строку и печатает содержимое строки.Поскольку вы видите d, это означает, что ваша система использует ascii, поскольку символ 'd' имеет целочисленное представление 100.Чтобы увидеть 100, вам нужно привести его к int как

std::cout << "Packet Size: " << static_cast<int>(*environment_struct->packetSize) << endl;

Обратите внимание, что поскольку packetSize является массивом из двух символов, вы не можете назначить одинзначение, которое занимает все это пространство.Если вы хотите это, вам нужно использовать фиксированные типы ширины, такие как

typedef struct ENVIRONMENT_STRUCT{
    uint8_t packetID; // unsigned integer that is exactly 8 bits wide.  Will be a compiler error if it does not exist
    uint16_t packetSize; // unsigned integer that is exactly 16 bits wide.  Will be a compiler error if it does not exist
};

int main()
{
    ENVIRONMENT_STRUCT * environment_struct = new ENVIRONMENT_STRUCT();
    environment_struct->packetSize = 100;
    std::cout << "Packet Size: " << environment_struct->packetSize << std::endl;
}
0 голосов
/ 09 октября 2018

Поскольку packetSize объявлен как тип символа, он выводится как символ.(ASCII-код символа 'd' равен 100 ...)

Попробуйте привести его к целочисленному типу:

std::cout << "Packet Size: " << (int)environment_struct->packetSize << endl;

В качестве альтернативы, поскольку вы хотите сохранить число как2-байтовый тип, вы можете избежать такого приведения и просто объявить packetSize как unsigned short.cout будет интерпретироваться как целочисленный тип.

...