10

我想在机器 A 上打印一个十六进制格式的字符串。比如:

ori_mesg = gen_rdm_bytestream (1400, seed)
sendto(machine B, ori_mesg, len(mesg))

在机器 B 上

recvfrom(machine A, mesg)

mesg_check = gen_rdm_bytestream (1400, seed)

for(i=0;i<20;i++){
    printf("%02x ", *(mesg+i)& 0xFF);
}
printf("\n");
for(i=0; i<20; i++){
    printf("%02x ", *(mesg_check+i));
}
printf("\n");

seed在 1、2、3、... 之间变化

字节生成函数是:

u_char *gen_rdm_bytestream (size_t num_bytes, unsigned int seed)
{
    u_char *stream = malloc (num_bytes+4);
    size_t i;

    u_int16_t seq = seed;
    seq = htons(seq);
    u_int16_t tail = num_bytes;
    tail = htons(tail);
    memcpy(stream, &seq, sizeof(seq));
    srand(seed);
    for (i = 3; i < num_bytes+2; i++){
        stream[i] = rand ();
    }
    memcpy(stream+num_bytes+2, &tail, sizeof(tail));

    return stream;
}

但是我从 printf 得到了结果,例如:

00 01 00 67 c6 69 73 51 ff 4a ec 29 cd ba ab f2 fb e3 46 7c
00 01 00 67 ffffffc6 69 73 51 ffffffff 4a ffffffec 29 ffffffcd ffffffba ffffffab fffffff2 fffffffb ffffffe3 46 7c

或者

00 02 88 fa 7f 44 4f d5 d2 00 2d 29 4b 96 c3 4d c5 7d 29 7e
00 02 00 fffffffa 7f 44 4f ffffffd5 ffffffd2 00 2d 29 4b ffffff96 ffffffc3 4d ffffffc5 7d 29 7e

为什么有这么多fffff用于mesg_check

这种现象有什么潜在的原因吗?

4

2 回答 2

23

这是一个小程序,说明了我认为您可能遇到的问题:

#include <stdio.h>
int main(void) {
    char arr[] = { 0, 16, 127, 128, 255 };
    for (int i = 0; i < sizeof arr; i ++) {
        printf(" %2x", arr[i]);
    }
    putchar('\n');
    return 0;
}

在我的系统上(在其char上签名),我得到这个输出:

  0 10 7f ffffff80 ffffffff

255,当存储在 (signed)char中时,存储为-1。在printf调用中,它被提升为 (signed) int- 但"%2x"格式告诉printf将其视为unsigned int,因此它显示fffffffff

确保您的mesgmesg_check数组被定义为数组unsigned char,而不是普通数组char

更新:一年多后重读这个答案,我意识到它不太正确。这是一个可以在我的系统上正常运行的程序,并且几乎肯定可以在任何合理的系统上运行:

#include <stdio.h>
int main(void) {
    unsigned char arr[] = { 0, 16, 127, 128, 255 };
    for (int i = 0; i < sizeof arr; i ++) {
        printf(" %02x", arr[i]);
    }
    putchar('\n');
    return 0;
}

输出是:

 00 10 7f 80 ff

type 的参数unsigned char被提升为 (signed) int(假设它int可以保存所有类型的值unsigned char,即 ,INT_MAX >= UCHAR_MAX实际上在所有系统上都是这种情况)。所以参数arr[i]被提升为int,而" %02x"格式需要一个类型的参数unsigned int

C 标准强烈暗示,但没有完全直接说明,相应的有符号和无符号类型的参数是可以互换的,只要它们在这两种类型的范围内——这里就是这种情况。

为了完全正确,您需要确保参数实际上是 type unsigned int

printf("%02x", (unsigned)arr[i]);
于 2013-04-04T23:58:51.027 回答
-1

是的,始终以十六进制格式将字符串打印为:

for(i=0; till string length; i++)
    printf("%02X", (unsigned char)str[i]);

当您尝试一次打印整个字符串时,如果字符串的格式不是'unsigned char' ,则在使用'unsigned char'的字符一个字符地打印十六进制字符串时,会出现错误。

于 2017-04-14T04:36:28.937 回答