Comment transformer une chaîne hexadécimale dans un unsigned char tableau?
Par exemple, j'ai une cstring "E8 48 D8 FF FF 8B 0D"
(espaces compris) qui doit être converti en équivalent unsigned char tableau {0xE8,0x48,0xD8,0xFF,0xFF,0x8B,0x0D}
. Ce qui est une manière efficace de faire cela? Merci!
EDIT: je ne peux pas utiliser les std bibliothèque... donc considérer cela comme un C question. Je suis désolé!
OriginalL'auteur Gbps | 2010-07-10
Vous devez vous connecter pour publier un commentaire.
Vous ne serez jamais à me convaincre que cette opération est un goulot d'étranglement des performances.
Le moyen efficace est de faire bon usage de votre temps à l'aide de la bibliothèque standard C:
Compilé et testé. Fonctionne sur votre exemple.
Otoh, que, dépassement de tampon sur "A B C D E F 1 2 3 4 5 6 7 8 9".
Beaucoup plus simple:
for (i=0; i<max && isxdigit(*s); i++) a[i]=strtol(s, &s, 16);
Le point de l'être, votregethex
fonction est totalement superflus.strtol
ignore les principaux espaces de lui-même. Si vous voulez être plus strict sur les pas de l'acceptation des chaînes qui ne correspondent pas au modèle, vous pouvez utiliser sscanf pour le contrôle de la largeur de champ et de mesurer les longueurs correspondent.grand point sur strtoul---je n'ai pas lu la page de man assez attentivement. N'hésitez pas à modifier.
On ne fonctionne correctement que si les espaces sont présents dans tous les deux les chiffres. De l'OMI, ce qui rend cette approche de merde.
OriginalL'auteur Norman Ramsey
Ceci répond à la original question, qui a demandé un C++ solution.
Vous pouvez utiliser un
istringstream
avec lehex
manipulateur:Noter que
c
doit être unint
(oulong
, ou d'un autre type entier), pas unchar
; si c'est unchar
(ouunsigned char
), le mauvais>>
surcharge sera appelée, et des caractères individuels seront extraits de la chaîne, pas entier hexadécimal de chaînes.Erreur supplémentaire de vérification pour s'assurer que la valeur extraite s'inscrit dans un
char
serait une bonne idée.Parce que je ne peut pas donner deux réponses correctes, je suis allé de l'avant et upvoted celui-ci, comme c'est certainement une excellente solution pour C++ utilisateurs!
OriginalL'auteur
(ch >= 'A')? (ch - 'A' + 10): (ch - '0')
.C'est en gros ce que j'ai fait, sauf pour l'utilisation de l'interrupteur à la place de ternaire de test. En fonction du compilateur et de l'architecture du processeur de l'un ou l'autre peut être plus rapide. Mais vous devez également tester chaque personnage est dans une plage de 0-9A-F, et il permet de tester la même chose deux fois.
Tout est dans les hypothèses. Vous partez du principe qu'il doit y avoir exactement deux chiffres hexadécimaux, et un espace entre chaque valeur de la mine permet l'omission d'un zéro ou plusieurs espaces, mais suppose qu'il n'y a pas d'autres classes de caractères dans la chaîne. Si vous ne pouvez pas supposer que, je serais probablement choisir de valider séparément, par l'analyse des
if (s[strspn(s, " 0123456789ABCDEF")]) /* error */;
bien Sûr, c'est un autre passage sur la chaîne, mais bien plus propre. Ou d'éviter le deuxième passage sur la chaîne en utilisantisspace
etisxdigit
sur chaque personnage, qui utilise une table de recherche pour la vitesse.Boucle autour des interrupteurs n'est pas vraiment un problème, je n'ai pas vraiment le prendre comme une différence. J'ai choisi de supposer qu'il y a exactement deux hex de chevalier dans l'entrée, parce que si vous permettez à plus de que vous devriez également vérifier la plage de valeurs. Et que dire de permettre negativer numéros, nous aurions à gérer signe, etc. commutateur est une sorte de table de recherche... (et un autre à la conversion rapide de la méthode à utiliser réellement une mise en œuvre comme un tableau).
Le problème précisé que toutes les entrées ont été signés. Le problème n'a pas de préciser qu'il y aurait toujours des zéros de rembourrage pour exactement deux chiffres (par exemple, tous ceux-ci s'intègrent dans un
char
:0xA
,0x0A
,0x000A
) ou tout simplement un espace, bien que ces hypothèses étaient vraies sur l'échantillon d'entrée.OriginalL'auteur Ben Voigt
Si vous connaissez la longueur de la chaîne à être analysée à l'avance (par exemple, vous lisez quelque chose à partir de /proc), vous pouvez utiliser sscanf avec le 'hh' modificateur de type, ce qui indique que la conversion suivante est l'une des diouxX et le pointeur de stocker ce sera soit signé char ou unsigned char.
De sortie:
OriginalL'auteur Diego Medaglia
utiliser le "vieux" sscanf() fonction:
OriginalL'auteur amigo
Pour un pur C mise en œuvre, je pense que vous pouvez vous persuader
sscanf(3)
de faire ce que vous ce que. Je crois que ce doit être portable (y compris la légèrement douteux de contrainte de type pour apaiser le compilateur) aussi longtemps que votre chaîne d'entrée n'est jamais que va contenir deux caractères des valeurs hexadécimales.c
commeunsigned int
, sinon vous risqueriez d'écraser les autres variables locales (ou pire encore, votre adresse de retour).Mais en général, scanf va prendre plus de temps pour trouver le code de format que l'ensemble de ma réponse, et la question a poser pour un efficace.
Voigt. Oui, mais n'moyen efficace d'exécution ou de programmeur à temps? '-) En tout cas merci de remarquer que j'aurais dû faire
c
uninsigned int
et des contraintes que dans laresult
tableau.UB. Depuis attendues fin
p
points d'un octet APRÈS la fin de zéro.Bonne prise. J'étais clairement dans deux esprits écrit ceci (il y a 6 ans), après avoir déclaré un
cnt
variable et ensuite de ne pas l'avoir utiliséOriginalL'auteur bjg
L'ancien comme en C, le faire à la main 😉 (il est beaucoup plus courte façons, mais je ne suis pas le golf, je vais pour le moment de l'exécution).
Maintenant une autre que de permettre à un nombre quelconque de chiffres entre les nombres, un nombre quelconque d'espaces pour séparer la tête ou les espaces (Ben specs):
Non, ce n'est pas vraiment d'obfuscation... mais bon, on dirait qu'il est.
pas du tout... j'aurais peut-être ajouté un espace à l'entrée. Le vieux séparateurs vs terminateurs de débat.
votre petit correctif n'aide pas...
*p != ' '
sur la résiliation NUL et il n'a pas d'importance ce que vous logique ou que avec.Opps, je n'ai tromper de nouveau. Vous souhaitez de la nouvelle fix mieux 🙂
Un contrôle de validité est encore feuilletée.
OriginalL'auteur kriss