[英]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';
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];
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.