10

マシン A で文字列を 16 進形式で出力したい。

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");

seed1、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、(署名済み) に昇格されますintが、"%2x"形式ではprintfとして扱うように指示されているunsigned intため、 が表示されますfffffffff

あなたmesgと配列がプレーンではなくmesg_checkの配列として定義されていることを確認してください。unsigned charchar

更新: 1 年以上後にこの回答を読み直すと、それが完全に正しくないことがわかります。これは私のシステムで正しく動作するプログラムであり、妥当なシステムであればほぼ確実に動作します。

#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) に昇格されます (が type のすべての値を保持できるintと仮定します。つまり、実質的にすべてのシステムに当てはまります)。したがって、引数は に昇格されますが、形式には型の引数が必要です。intunsigned charINT_MAX >= UCHAR_MAXarr[i]int" %02x"unsigned int

C 標準は、対応する符号付き型と符号なし型の引数が両方の型の範囲内にある限り交換可能であることを強く示唆していますが、直接的には述べていません

完全に正しくするには、引数が実際に型であることを確認する必要がありますunsigned int

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