1

我会在 char 数组中复制一个 uint8_t 数组。我尝试了不同的解决方案:cast、memcopy、strcpy ......但它不起作用!!!我的小例子是:

uint32_t num = 123456789;
printf("\n num: %"PRIu32 "\n", num);
uint32_t x;
uint8_t a[4];
char b[4];

num=htonl(num);

a[0]=num;
a[1]=num>>8;
a[2]=num>>16;
a[3]=num>>24;

b[0] = a[0];
b[1] = a[1];
b[2] = a[2];
b[3] = a[3];



printf("\nA: %x %x %x %x", a[0],a[1],a[2],a[3]);
printf("\nB: %x %x %x %x", b[0],b[1],b[2],b[3]);


x= b[0] | b[1]<<8 | b[2]<<16 | b[3]<<24;

x=ntohl(x);
printf("\n x vale: %"PRIu32 "\n", x);
}

印刷品是:

num: 123456789
A: 7 5b cd 15
B: 7 5b ffffffcd 15
x: 123457023

为什么我在 x 中得到不同的数字?

4

2 回答 2

0

您必须稍微修改您的代码以确保处理一些未定义的行为,例如signed int值溢出。

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <arpa/inet.h>

int main()
{
    uint32_t num = 123456789;
    printf("\n num: %" PRIu32 "\n", num);
    uint32_t x;
    uint8_t a[4];
    unsigned char b[4];

    num=htonl(num);

    a[0] = num & 0x000000FFu;
    a[1] = (num & 0x0000FF00u) >> 8;
    a[2] = (num & 0x00FF0000u) >>16;
    a[3] = (num & 0xFF000000u) >>24;

    b[0] = a[0];
    b[1] = a[1];
    b[2] = a[2];
    b[3] = a[3];


    printf("\nA: %x %x %x %x", a[0],a[1],a[2],a[3]);
    printf("\nB: %x %x %x %x", b[0], b[1], b[2], b[3]);


    x = b[0] | (b[1] & 0x000000FFu)<<8 | (b[2] & 0x000000FFu)<<16 | (b[3] & 0x000000FFu)<<24;

    x = ntohl(x);

    printf("\n x vale: %" PRIu32 "\n", x);

    return 0;
}

如你看到的:

  1. b数组被声明为unsigned char避免未定义的行为。它还更正printf了代码中 3rd 打印的值。
  2. 将值插入a数组中,如果在将它们移动到正确位置之前屏蔽要移动的位,则更清楚。
  3. 当您计算值时,您正在对变量x执行左移。8 bit所以你在 8 次移位后丢失了所有位。用 a &ing 他们32 bit HEX literal可以确保为位移和ors使用正确的大小

关于第 3 点,正如@2501 指出的那样,您必须将 u 用于文字,以确保避免在int大小小于 32 bts 或 signed int 具有陷阱值的平台上使用 UB。见 6.4.4.1。p5 标准。

于 2016-05-30T15:19:57.047 回答
0

我不明白为什么调用不memcpy应该工作。只需检查CHAR_BIT == 8以确保char定义为 8 位类型(某些实现定义char为 16 位大),然后调用memcpy(b, a, sizeof(b) / sizeof(b[0])). 这应该是诀窍。不要忘记包括string.hformemcpylimits.hfor CHAR_BIT


正如其他人指出的那样,您仍然可能会遇到麻烦,因为 的签名char也是实现定义的。因此,您应该声明bunsigned char防止未定义的行为。

要 100% 保存,您还应该检查它a并且b确实具有相同的大小,这样您就不会遇到任何运行时错误。

于 2016-05-30T15:21:41.683 回答