【问题标题】:How to concatenate the hexadecimal data in an array in C如何在C中连接数组中的十六进制数据
【发布时间】:2018-12-03 09:10:34
【问题描述】:

我的数据字段如下DATA = 0x02 0x01 0x02 0x03 0x04 0x05 0x06 0x07 现在我想将这些数据连接起来如下DATA = 0x01020304050607。我如何使用 C 程序来做到这一点。我在C语言中找到了一个用于连接数组中数据的程序,程序如下:

#include<stdio.h>

int main(void)
{
    int num[3]={1, 2, 3}, n1, n2, new_num;
    n1 = num[0] * 100;
    n2 = num[1] * 10;
    new_num = n1 + n2 + num[2];
    printf("%d \n", new_num);
    return 0;
}

对于数组中的十六进制数据,我该如何操作上面的程序来连接十六进制数据?

【问题讨论】:

  • printf("%x", (unsigned int)((n[0] &lt;&lt; 16) + (n[1] &lt;&lt; 8) + n[2]));
  • char num[3]={1, 2, 3}吗?
  • 嗯,最简单的方法是const unsigned char data[] = {0x01, 0x02, 0x03, ...}; - 所有这些元素将按此顺序一个接一个地存储在连续的内存段中。
  • DATA = 0x01020304050607 需要一个 64 位变量。甚至 DATA = 0x0201020304050607 取决于您想要的版本。
  • data[] 的类型为uint8_t data[8];,不能为unsigned char

标签: c arrays hex concatenation


【解决方案1】:

你需要一个 64 位变量 num 作为结果,而不是 10 作为你需要 16 的因素,而不是 100 作为因素,你需要 256

但如果您的数据以字节数组的形式提供,那么您可以简单地插入完整的字节,即重复移位 8 位(意味着 256 倍):

int main(void)
{
    uint8_t data[8] = { 0x02, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
    unsigned long long num = 0;
    for (int i=0; i<8; i++) {
        num <<=8;  // shift by a complete byte, equal to num *= 256
        num |= data[i];  // write the respective byte
    }
    printf("num is %016llx\n",num);
    return 0;
}

输出:

num is 0201020304050607

【讨论】:

  • 转换格式%llx 可能不适用于uint64_t。您应该将操作数转换为unsigned long long,或者简单地将这种类型用于num,因为它被指定为至少有64个值位。
【解决方案2】:

以下是一种将数据直接写入整数的技巧,无需任何位运算符:

#include <stdio.h>
#include <stdint.h>
#include <string.h>

uint64_t numberize(const uint8_t from[8]) {
    uint64_t r = 0;
    uint8_t *p = &r;

    #if '01' == 0x4849 // big endian
        memcpy(p, from, 8);
    #else // little endian
        for (int i=7; i >= 0; --i)
            *p++ = from[i];     
    #endif

    return r;
}

int main() {
    const uint8_t data[8] = { 0x02, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };

    printf("result is %016llx\n", numberize(data));

    return 0;
}

这个does work 并独立于你的机器的字节序输出这个:

result is 0201020304050607

编译时字节序测试取自this SO answer

【讨论】:

  • 根据 C 标准,预处理器字节顺序测试不可靠且未指定。您可以使用将由编译器优化的运行时检查,也可以使用简单易读的循环:int i; uint64_t r = 0; for (i = 0; i &lt; 8; i++) { r = (r &lt;&lt; 8) | from[i]; } return r;
  • 转换格式%llx 可能不适用于uint64_t。您应该将操作数转换为unsigned long long
【解决方案3】:

免得说你有类似的输入

int DATA[8] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};

如果你想要像0x0001020304050607 这样的输出,要存储这个结果输出,你需要一个unsigned long long 类型的变量。例如

int main(void) {
        int DATA[8] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};
        int ele = sizeof(DATA)/sizeof(DATA[0]);
        unsigned long long mask = 0x00;
        for(int row = 0; row < ele; row++) {
                mask = mask << 8;/* every time left shifted by 8(0x01-> 0000 0001) times   */
                mask = DATA[row] | mask; /* put at correct location */
        }
        printf("%016llx\n",mask);
        return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-18
    • 2014-01-04
    • 1970-01-01
    • 1970-01-01
    • 2014-12-12
    • 2017-08-26
    • 2020-09-08
    • 2011-06-01
    相关资源
    最近更新 更多