utilisez printf pour imprimer une chaîne de caractères au format hexadécimal, avec des résultats déformés

Je veux imprimer une chaîne de caractères au format hexadécimal,

sur la machine A, quelque chose comme

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

sur la machine 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 varie entre 1, 2 3 ….

la fonction de génération d’octets est:

 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; } 

mais j’ai obtenu des résultats de printf comme:

 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 

ou

 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 

pourquoi y a-t-il tant de fffff pour mesg_check ?

Existe-t-il des raisons potentielles à ce phénomène? Merci!

Voici un petit programme qui illustre le problème que vous pourriez rencontrer:

 #include  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; } 

Sur mon système (sur lequel le caractère brut est signé), j'obtiens cette sortie:

  0 10 7f ffffff80 ffffffff 

La valeur 255 , lorsqu'elle est stockée dans un caractère (signé), est stockée sous la forme -1 . Dans l'appel printf , il est promu à (signé) int - mais le format "%2x" indique à printf de le traiter comme un unsigned int , de sorte qu'il affiche fffffffff .

Assurez-vous que vos tableaux mesg et mesg_check sont définis en tant que tableaux de caractères unsigned char , pas de caractères simples.

MISE À JOUR: En relisant cette réponse plus d'un an plus tard, je me rends compte que ce n'est pas tout à fait correct. Voici un programme qui fonctionne correctement sur mon système et fonctionnera presque certainement sur tout système raisonnable:

 #include  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; } 

La sortie est:

  00 10 7f 80 ff 

Un argument de type unsigned char est promu en (signed) int (en supposant que int puisse contenir toutes les valeurs de type unsigned char , c'est-à-dire INT_MAX >= UCHAR_MAX , ce qui est le cas sur pratiquement tous les systèmes). Ainsi, l'argument arr[i] est promu en int , alors que le format " %02x" nécessite un argument de type unsigned int .

La norme C implique fortement, mais ne précise pas directement, que les arguments des types signés et non signés correspondants sont interchangeables dans la mesure où ils se situent dans la plage des deux types - ce qui est le cas ici.

Pour être complètement correct, vous devez vous assurer que l'argument est bien du type unsigned int :

 printf("%02x", (unsigned)arr[i]); 

Oui, toujours imprimer la chaîne au format hexadécimal comme:

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

vous aurez une erreur lorsque vous essayez d’imprimer

toute la chaîne en une fois et lors de l’impression chaîne hexadécimale, caractère par caractère, qui utilise “Caractère non signé” si la chaîne est dans un format autre que “Caractère non signé”