Comment convertir correctement un Hex Ssortingng en Byte Array en C?

Je dois convertir une chaîne contenant des valeurs hexadécimales sous forme de caractères dans un tableau d’octets. Bien que cela ait déjà été répondu ici comme première réponse, j’obtiens l’erreur suivante:

warning: ISO C90 does not support the 'hh' gnu_scanf length modifier [-Wformat] 

Puisque je n’aime pas les avertissements et que l’omission de hh crée simplement un autre avertissement

 warning: format '%x' expects argument of type 'unsigned int *', but argument 3 has type 'unsigned char *' [-Wformat] 

ma question est: comment faire cela correctement? Pour terminer, je poste à nouveau l’exemple de code ici:

 #include  int main(int argc, char **argv) { const char hexssortingng[] = "deadbeef10203040b00b1e50", *pos = hexssortingng; unsigned char val[12]; size_t count = 0; /* WARNING: no sanitization or error-checking whatsoever */ for(count = 0; count < sizeof(val)/sizeof(val[0]); count++) { sscanf(pos, "%2hhx", &val[count]); pos += 2 * sizeof(char); } printf("0x"); for(count = 0; count < sizeof(val)/sizeof(val[0]); count++) printf("%02x", val[count]); printf("\n"); return(0); } 

    Vous pouvez utiliser strtol() place.

    Remplacez simplement cette ligne:

     sscanf(pos, "%2hhx", &val[count]); 

    avec:

     char buf[10]; sprintf(buf, "0x%c%c", pos[0], pos[1]); val[count] = strtol(buf, NULL, 0); 

    UPDATE : Vous pouvez éviter d’utiliser sprintf() utilisant cet extrait à la place:

     char buf[5] = {"0", "x", pos[0], pos[1], 0}; val[count] = strtol(buf, NULL, 0); 

    Vous pouvez soit basculer votre compilateur en mode C99 (le modificateur de longueur hh été normalisé en C99), ou vous pouvez utiliser une variable temporaire unsigned int :

     unsigned int byteval; if (sscanf(pos, "%2x", &byteval) != 1) { /* format error */ } val[count] = byteval; 

    Pourquoi ne pas le faire sans utiliser sscanf, strol, etc. Ci-dessous, HexToBin et Bin-To-Hex. (Remarque: à l’origine, des codes d’erreur Enum avaient été renvoyés via un système de consignation d’erreurs, et non une simple déclaration -1.)

     unsigned char HexChar (char c) { if ('0' <= c && c <= '9') return (unsigned char)(c - '0'); if ('A' <= c && c <= 'F') return (unsigned char)(c - 'A' + 10); if ('a' <= c && c <= 'f') return (unsigned char)(c - 'a' + 10); return 0xFF; } int HexToBin (const char* s, unsigned char * buff, int length) { int result; if (!s || !buff || length <= 0) return -1; for (result = 0; *s; ++result) { unsigned char msn = HexChar(*s++); if (msn == 0xFF) return -1; unsigned char lsn = HexChar(*s++); if (lsn == 0xFF) return -1; unsigned char bin = (msn << 4) + lsn; if (length-- <= 0) return -1; *buff++ = bin; } return result; } void BinToHex (const unsigned char * buff, int length, char * output, int outLength) { char binHex[] = "0123456789ABCDEF"; if (!output || outLength < 4) return; *output = '\0'; if (!buff || length <= 0 || outLength <= 2 * length) { memcpy(output, "ERR", 4); return; } for (; length > 0; --length, outLength -= 2) { unsigned char byte = *buff++; *output++ = binHex[(byte >> 4) & 0x0F]; *output++ = binHex[byte & 0x0F]; } if (outLength-- <= 0) return; *output++ = '\0'; } 

    En utilisant les modifications suggérées par mvp, j’ai créé cette fonction qui inclut la vérification des erreurs (caractères non valides et longueur inégale).

    Cette fonction convertira une chaîne hexadécimale – PAS précédée de “0x” – avec un nombre pair de caractères pour le nombre d’octets spécifié. Il renverra -1 s’il rencontre un caractère non valide ou si la chaîne hexadécimale a une longueur impaire, et 0 en cas de succès.

     //convert hexssortingng to len bytes of data //returns 0 on success, -1 on error //data is a buffer of at least len bytes //hexssortingng is upper or lower case hexadecimal, NOT prepended with "0x" int hex2data(unsigned char *data, const unsigned char *hexssortingng, unsigned int len) { unsigned const char *pos = hexssortingng; char *endptr; size_t count = 0; if ((hexssortingng[0] == '\0') || (strlen(hexssortingng) % 2)) { //hexssortingng contains no data //or hexssortingng has an odd length return -1; } for(count = 0; count < len; count++) { char buf[5] = {'0', 'x', pos[0], pos[1], 0}; data[count] = strtol(buf, &endptr, 0); pos += 2 * sizeof(char); if (endptr[0] != '\0') { //non-hexadecimal character encountered return -1; } } return 0; }