Скопируйте массив uint8_t в структуру - PullRequest
0 голосов
/ 22 января 2019

У меня есть этот массив

uint8_t *buffer = "JOHN:DOE:010119:M:FOO:BAR";

, и я хочу скопировать его поле за полем в структуру данных

typedef struct{
  uint8_t firstName[5];
  uint8_t pad1;
  uint8_t lastName[4];
  uint8_t pad2;
  uint8_t dateOfBirth[7];
  uint8_t pad3;
  uint8_t genre;
  uint8_t pad4;
  uint8_t car[4];
  uint8_t pad5;
  uint8_t phone[4];
  uint8_t pad6;
}DataStructTypeDef;

Допустим, все длины фиксированы (например, firstNameвсегда состоит из 4 символов, lastName из 3 и т. д.)

Я использовал этот подход:

DataStructTypeDef foo;
memcpy((void *)&foo, (void *)buffer, sizeof(DataStructTypeDef));

Когда я пытаюсь напечатать dateOfBirth, он показывает весь массивначиная с 01012019 вот так

int main(void)
{
  DataStructTypeDef foo;
  memcpy((void *)&foo, (void *)buffer, sizeof(DataStructTypeDef));
  printf("%s", foo.dateOfBirth); // It prints 010119:M:FOO:BAR
//printf("%s", foo.dateOfBirth); // Expected value 010119
  return 0;
}

Ответы [ 4 ]

0 голосов
/ 22 января 2019
  1. Измените свою структуру

Добавьте дополнительный байт в каждое поле для размещения символа '\ 0'. Например, используйте

uint8_t firstName[5];

вместо

uint8_t firstName[4];
  1. Разобрать поля по отдельности и завершить каждое поле '\ 0'

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

0 голосов
/ 22 января 2019

С фиксированной структурой

typedef struct {
    uint8_t firstName[4];
    uint8_t pad1;
    uint8_t lastName[3];
    uint8_t pad2;
    uint8_t dateOfBirth[6];
    uint8_t pad3;
    uint8_t genre;
    uint8_t pad4;
    uint8_t car[3];
    uint8_t pad5;
    uint8_t phone[3];
    uint8_t pad6;
}DataStructTypeDef;

Это работает для меня:

int main(void)
{
    uint8_t *buffer = "JOHN" "\0" "DOE" "\0" "010119" "\0" "M" "\0" "FOO" "\0" "BAR";
    DataStructTypeDef foo;
    memcpy((void *)&foo, (void *)buffer, sizeof(DataStructTypeDef));
    printf("%s", foo.dateOfBirth); // Expected value 01012019
}

Буфер выглядит ужасно искаженным, потому что если я поставлю "\0" "010119" как "\0010119", это интерпретируетпобег не в ту сторону.Возможно, лучшим решением было бы сохранить его как единое целое и полностью записать восьмеричную последовательность как \000:

uint8_t *buffer = "JOHN\000DOE\000010119\000M\000FOO\000BAR";

Здесь каждый \000 становится нулевым байтом и не конфликтует с010119 после одной из escape-последовательностей.

В качестве альтернативы, это работает, если я беру исходную строку буфера "JOHN:DOE:010119:M:FOO:BAR" и просто заменяю все : после копирования, например:

foo.pad1 = foo.pad2 = foo.pad3 = foo.pad4 = foo.pad5 = foo.pad6 = '\0';
0 голосов
/ 22 января 2019

После memcpy добавить это: foo.pad1 = foo.pad2 = foo.pad3 = foo.pad4 = foo.pad5 = 0;. Но я надеюсь, что это упражнение, а не реальная структура для реальной работы.

0 голосов
/ 22 января 2019

Поскольку копируемые элементы char array не имеют нулевого завершения, printf("%s", не будет знать, когда он встретил конец каждой строки.

Это можно контролировать в printf, ограничивая количество печатаемых символов ...

Например:

printf("%.*s", (int)sizeof(foo.dateOfBirth), foo.dateOfBirth);

Эквивалент будет:

printf("%.6s", food.dateOfBirth);

.* указывает «точность» символов, которые вы хотите напечатать. Так что в вашем случае dateOfBirth = точность / размер 6.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...