如何将数组的值设置为单个变量

时间:2019-06-16 05:56:52

标签: c arrays

我正在从ARM micro的SD卡中读取值:

Res = f_read(&fil, (void*)buf, 6, &NumBytesRead);

其中fil是指针,buf是存储数据的缓冲区。

这就是问题所在:这是一个数组,但是我想将该数组的内容放在一个变量中。

举一个实际的例子:从文件中读取的6个字节是:

buf[0] = 0x1B
buf[1] = 0x26
buf[2] = 0xB3
buf[3] = 0x54
buf[4] = 0xA1
buf[5] = 0xCF

我想拥有:uint64_t data等于0x1B26B354A1CF。也就是说,数组的所有元素都以一个64位整数“串联”。

3 个答案:

答案 0 :(得分:6)

无需键入修剪,您可以执行以下操作。

.d.ts

答案 1 :(得分:3)

使用并集,但要记住字节序。

 union 
 {
      uint8_t u8[8];
      uint64_t u64;
  }u64;

typedef联合 {     uint8_t u8 [8];     uint64_t u64; } u64;

typedef enum
{
    LITTLE_E,
    BIG_E,
}ENDIANESS;

ENDIANESS checkEndianess(void)
{
    ENDIANESS result = BIG_E;
    u64 d64 = {.u64 = 0xff};
    if(d64.u8[0]) result = LITTLE_E;

    return result;
}

uint64_t arrayToU64(uint8_t *array, ENDIANESS e) // for the array BE
{
    u64 d64;
    if(e == LITTLE_E)
    {
        memmove(&d64, array, sizeof(d64.u64));
    }
    else
    {
        for(int index = sizeof(d64.u64) - 1; index >= 0; index--)
        {
            d64.u8[sizeof(d64.u64) - index - 1] = array[index];
        }
    }
    return d64.u64;
}

int main()
{
    uint8_t BIG_E_Array[] = {0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80};
    ENDIANESS e;

    printf("This system endianess: %s\n", (e = checkEndianess()) == BIG_E ? "BIG":"LITTLE");

    printf("Punned uint64_t for our system 0x%lx\n", arrayToU64(BIG_E_Array, e));
    printf("Punned uint64_t for the opposite endianess system 0x%lx\n", arrayToU64(BIG_E_Array, e == BIG_E ? LITTLE_E : BIG_E));

    return 0;
}

答案 2 :(得分:0)

要照顾的事情在这里:

  1. 具有正确的字节顺序
  2. 将六个字节读取为一个64位整数

通过使用以下两个marcos将以网络字节顺序(Big Endian)进入的字节存储到主机字节顺序的64位整数中,可以解决问题1。

    /* below defines of htonll() and ntohll() are taken from this answer:
       https://stackoverflow.com/a/28592202/694576
     */
    #if __BIG_ENDIAN__
    # define htonll(x) (x)
    # define ntohll(x) (x)
    #else
    # define htonll(x) ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32))
    # define ntohll(x) ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32))
    #endif

问题2可以通过多种方式解决:

  1. 扩展您的方法

    #define BUFFER_SIZE (6)
    
    ...
    
      assert(BUFFER_SIZE <= sizeof (uint64_t)); 
    
      uint8_t buffer[BUFFER_SIZE];
      FILE * pf = ...; /* open file here */
      /* test if file has been opened successfully here */
    
      ... result = f_read(pf, buffer, BUFFER_SIZE, ...);
      /* test result for success */
    
      uint64_t number = 0;
      memset(&number, buffer, BUFFER_SIZE)
      number = ntohll(number);
    
  2. 通过并集使用“ Type Punning

    union buffer_wrapper
    {
      uint8_t u8[sizeof (uint64_t)];
      uint64_t u64;
    }
    

    代替

      uint8_t buffer[BUFFER_SIZE];
    

    使用

      union buffer_wrapper buffer;
    

    而不是

      memcpy(&number, buffer, BUFFER_SIZE)
      number = ntohll(number)
    

    使用

      number = ntohll(buffer.u64)