簡體   English   中英

將uint8_t數組復制到結構

[英]Copy a uint8_t array to a struct

我有這個數組

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;
}

由於您復制的char array成員不是以null結尾,因此printf("%s",在遇到每個字符串的結尾時都不知道。

這可以通過限制打印的字符數量來控制printf ...

例如:

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

相當於:

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

.*指定要打印的字符的“精度”。 所以在你的情況下, dateOfBirth = precision / size 6。

用固定的結構

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';
  1. 修改你的結構

為每個字段添加一個額外的字節以容納'\\ 0'字符。 例如用途

uint8_t firstName[5];

代替

uint8_t firstName[4];
  1. 單獨解析字段並以'\\ 0'結束每個字段

不是一次復制整個緩沖區,而是逐個復制元素。 由於每個字段的大小是固定的,因此從緩沖區起始處的偏移量是固定的,這使得解析工作更容易。

memcpy之后添加: foo.pad1 = foo.pad2 = foo.pad3 = foo.pad4 = foo.pad5 = 0; 但我希望這是鍛煉,而不是真正的工作結構。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM