简体   繁体   English

将uint8_t数组复制到结构

[英]Copy a uint8_t array to a struct

I have this array 我有这个数组

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

and I want to copy it field by field to data structure 我想逐字段地将它复制到数据结构中

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;

Let's say that all lengths are fixed (eg. firstName is always composed of 4 characters, lastName of 3 etc ...) 假设所有长度都是固定的(例如, firstName总是由4个字符组成, lastName为3等...)

I used this approach: 我用这种方法:

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

When I try to print dateOfBirth it shows the whole array starting from 01012019 like this 当我尝试打印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;
}

Since the char array members you are copying are not null terminated, printf("%s", will not know when it has encountered the end of each string. 由于您复制的char array成员不是以null结尾,因此printf("%s",在遇到每个字符串的结尾时都不知道。

This can be controlled in printf by limiting the amount of characters that print... 这可以通过限制打印的字符数量来控制printf ...

For example: 例如:

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

An equivalent would be: 相当于:

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

.* specifies the "precision" of characters you want to print. .*指定要打印的字符的“精度”。 So in your case, dateOfBirth = precision/size 6. 所以在你的情况下, dateOfBirth = precision / size 6。

With the fixed struct of 用固定的结构

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;

This works for me: 这对我有用:

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
}

The buffer looks horribly mangled because if I put "\\0" "010119" as "\\0010119" , it's interpreting the escape the wrong way. 缓冲区看起来非常糟糕,因为如果我将"\\0" "010119""\\0010119" ,它就会以错误的方式解释转义。 A better solution would probably be to keep it as one and fully write out the octal sequence as \\000 : 一个更好的解决方案可能是将它保持为一个并完全写出八进制序列为\\000

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

Here, each \\000 becomes a null byte and it doesn't clash with the 010119 following one of the escape sequences. 这里,每个\\000变为空字节,并且它不会跟随其中一个转义序列与010119冲突。

Alternatively, it works if I take the original buffer string of "JOHN:DOE:010119:M:FOO:BAR" and just replace all the : after copying, like this: 或者,如果我使用"JOHN:DOE:010119:M:FOO:BAR"的原始缓冲区字符串并且在复制后替换所有:它,它会起作用,如下所示:

foo.pad1 = foo.pad2 = foo.pad3 = foo.pad4 = foo.pad5 = foo.pad6 = '\0';
  1. Modify your structure 修改你的结构

Add an extra byte to each field to accommodate the '\\0' character. 为每个字段添加一个额外的字节以容纳'\\ 0'字符。 For eg use 例如用途

uint8_t firstName[5];

instead of 代替

uint8_t firstName[4];
  1. Parse the fields individually and end each field with '\\0' 单独解析字段并以'\\ 0'结束每个字段

Instead of copying the entire buffer in one go, copy the elements one by one. 不是一次复制整个缓冲区,而是逐个复制元素。 Since, the size of each field is fixed, the offset from the start of the buffer is fixed and this makes the job of parsing easier. 由于每个字段的大小是固定的,因此从缓冲区起始处的偏移量是固定的,这使得解析工作更容易。

After memcpy add this: foo.pad1 = foo.pad2 = foo.pad3 = foo.pad4 = foo.pad5 = 0; memcpy之后添加: foo.pad1 = foo.pad2 = foo.pad3 = foo.pad4 = foo.pad5 = 0; . But I hope this is exercise, not a real structure for real job. 但我希望这是锻炼,而不是真正的工作结构。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM