我有这个数组
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;
}
答案 0 :(得分:6)
由于您要复制的char array
成员不是以null结尾的,所以printf("%s",
将不知道何时遇到每个字符串的结尾。
这可以在printf
中通过限制打印字符的数量来控制...
例如:
printf("%.*s", (int)sizeof(foo.dateOfBirth), foo.dateOfBirth);
等效项为:
printf("%.6s", food.dateOfBirth);
.*
指定要打印的字符的“精度”。因此,根据您的情况,dateOfBirth
=精度/尺寸6。
答案 1 :(得分:2)
具有固定的结构
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
发生冲突。
或者,如果我采用原始缓冲区字符串"JOHN:DOE:010119:M:FOO:BAR"
并在复制后仅替换所有:
,则可以使用该方法,
foo.pad1 = foo.pad2 = foo.pad3 = foo.pad4 = foo.pad5 = foo.pad6 = '\0';
答案 2 :(得分:2)
向每个字段添加一个额外的字节以容纳'\ 0'字符。例如使用
uint8_t firstName[5];
代替
uint8_t firstName[4];
与其一次复制整个缓冲区,不如逐个复制元素。由于每个字段的大小都是固定的,因此与缓冲区起始位置的偏移是固定的,这使得解析工作变得更加容易。
答案 3 :(得分:1)
在memcpy
之后添加:foo.pad1 = foo.pad2 = foo.pad3 = foo.pad4 = foo.pad5 = 0;
。但我希望这是锻炼,而不是真正的工作结构。