uint32_t after = 0xe1ca95ee;
char new_buf[4];
memcpy(new_buf, &after, 4);
printf("%x\n", *new_buf); // I want to print the content of new_buf
我想将after
的内容复制到new_buf
。但结果令人困惑。 printf
给了我ffffffee
。它看起来像一个地址。我已经取消引用new_buf
。
根据评论,我无法使用memcpy
或strncpy
来执行此任务。但为什么? memcpy
和strncpy
仅用于处理char *
?但after
的内容在记忆中。
PS:我知道我应该使用sprintf
或snprintf
。如果你可以解释为什么memcpy
和strncpy
不适合这种情况,我很感激。
答案 0 :(得分:5)
这就是问题所在:
printf("%x\n", *new_buf);
这为您提供了所要求的内容:它使用%x格式在 new_buf 位置打印 char 。该位置已经包含0xee(在您成功的memcpy之后,首先是最不重要的字节,因为您最有可能在Intel机器上,小端),但它打印为0xffffffee(负数),因为它是 char 而不是 unsigned char ,因为当然0xee是有符号字节(> 0x7F,最高位设置)
您应该使用:
printf("%x\n", *((unsigned int*)new_buf));
...编辑如下......
或者更确切地说:
printf("%x\n", *((uint32_t*)new_buf));
答案 1 :(得分:3)
如果你这样做:
int i;
for (i = 0; i < 4; i++) printf("%x\n", new_buf[i]);
你可以看到它打印
ffffffee
ffffff95
ffffffca
ffffffe1
所以你的字节都在那里。正如@GeorgeAndré所指出的,它们是有符号字节,所以你看到f
被填充到前面,因为数字是负的,它总是打印4个字节,ee
用32位表示{ {1}}。您可能在一个小端机器上,因此最低有效字节ffffffee
实际上存储在最低内存位置,这就是为什么在解除引用ee
时得到数字的“最后”字节的原因。另一部分已被其他人回答,您必须在打印期间将new_buf
声明为未签名或投票。
new_buf
或者
uint32_t after = 0xe1ca95ee;
char new_buf[4];
memcpy(new_buf, &after, 4);
printf("%x\n", *((unsigned char*)new_buf));
答案 2 :(得分:0)
char new_buf[4];
...
printf("%x\n", *new_buf);
无论您存储在new_buf
中的是什么,它的类型仍然是char[4]
。因此,*new_buf
的类型为char
(它与new_buf[0]
完全相同)。
因此,您获取整数的第一个 char (可能是高字节或低字节,具体取决于平台),将其自动提升为整数,然后打印作为基数为16的无符号整数。
memcpy
确实已将您的值复制到数组中,但如果要打印它,请使用
printf("%x\n", *(uint32_t *)new_buf);
或
printf("%02x%02x%02x%02x\n", new_buf[0], new_buf[1], new_buf[2], new_buf[3]);
(但请注意,在后一种情况下,您的字节顺序可能会颠倒,具体取决于平台)。
不要使用memcpy
,它不会从整数转换为字符串表示。
尝试
uint32_t after = 0xe1ca95ee;
char new_buf[1 + 2*sizeof(after)];
snprintf(new_buf, sizeof(new_buf), "%x", after);
printf("original %x formatted as '%s'\n", after, new_buf);
(缓冲区的大小为每个八位字节提供2个字符,加上一个用于nul-terminator)。