Je veux convertir une chaîne hexadécimale en un entier signé 32 bits en C ++.
Ainsi, par exemple, j'ai la chaîne hexadécimale "fffefffe". La représentation binaire de ceci est 111111111111111011111111111110. La représentation entière signée de ceci est: -65538.
Comment faire cette conversion en C ++? Cela doit également fonctionner pour les nombres non négatifs. Par exemple, la chaîne hexadécimale "0000000A", qui est 00000000000000000000000000001010 en binaire et 10 en décimal.
int
. "Entier signé 32 bits" pourrait être int32_t ou __int32 etc.Réponses:
utilisation
std::stringstream
l'exemple suivant produit
-65538
comme résultat:Dans le nouveau standard C ++ 11, vous pouvez utiliser quelques nouvelles fonctions utilitaires! plus précisément, il existe une famille de fonctions "chaîne à nombre" ( http://en.cppreference.com/w/cpp/string/basic_string/stol et http://en.cppreference.com/w/cpp/string/ basic_string / stoul ). Ce sont essentiellement des enveloppes minces autour des fonctions de conversion de chaîne en nombre de C, mais savent comment gérer un
std::string
Ainsi, la réponse la plus simple pour un code plus récent ressemblerait probablement à ceci:
REMARQUE: Voici ma réponse originale, qui, comme le dit la modification, n'est pas une réponse complète. Pour une solution fonctionnelle, collez le code au-dessus de la ligne :-).
Il semble que puisque
lexical_cast<>
est défini pour avoir une sémantique de conversion de flux. Malheureusement, les flux ne comprennent pas la notation "0x". Donc, leboost::lexical_cast
et ma main ont roulé un ne gèrent pas bien les cordes hexagonales. La solution ci-dessus qui définit manuellement le flux d'entrée sur hexa le gérera très bien.Boost a également quelques trucs pour le faire, qui a également de bonnes capacités de vérification des erreurs. Vous pouvez l'utiliser comme ceci:
Si vous n'avez pas envie d'utiliser boost, voici une version allégée du cast lexical qui ne vérifie pas les erreurs:
que vous pouvez utiliser comme ceci:
la source
std::hex
stringstream
s, il faut vérifierss.good() && ss.eof()
qu'aucune erreur ne s'est produite.Pour une méthode qui fonctionne à la fois avec C et C ++, vous pouvez envisager d'utiliser la fonction de bibliothèque standard strtol ().
la source
strtoul
pas utiliserstrtol
. Il y en aura+ overflow
lors de l'utilisation de strtol. Avecstrtoul
il n'y aura pas de débordement et la valeur retournée sera convertie enlong
pour produire un résultat correct (-65538). Donc, votre réponse est presque correcte :)Andy Buchanan, en ce qui concerne le respect du C ++, j'ai aimé le vôtre, mais j'ai quelques mods:
Utilisé comme
De cette façon, vous n'avez pas besoin d'un impl par type int.
la source
Un exemple de travail avec
strtoul
sera:strtol
se convertitstring
enlong
. Sur mon ordinateurnumeric_limits<long>::max()
donne0x7fffffff
. De toute évidence, c'est0xfffefffe
supérieur à0x7fffffff
. Doncstrtol
retourneMAX_LONG
au lieu de la valeur souhaitée.strtoul
convertitstring
enunsigned long
c'est pourquoi aucun débordement dans ce cas.Ok,
strtol
considère que la chaîne d'entrée n'est pas un entier signé de 32 bits avant la conversion. Échantillon amusant avecstrtol
:Le code ci-dessus s'imprime
-65538
dans la console.la source
Voici une méthode simple et fonctionnelle que j'ai trouvée ailleurs:
Veuillez noter que vous préférerez peut-être utiliser un entier long non signé / un entier long pour recevoir la valeur. Une autre note, la fonction c_str () convertit simplement le std :: string en const char *.
Donc, si vous avez un const char * prêt, continuez simplement à utiliser ce nom de variable directement, comme indiqué ci-dessous [Je montre également l'utilisation de la variable longue non signée pour un nombre hexadécimal plus grand. Ne le confondez pas avec le cas d'avoir const char * au lieu de string]:
Cela fonctionne parfaitement bien (à condition d'utiliser les types de données appropriés selon vos besoins).
la source
J'ai eu le même problème aujourd'hui, voici comment je l'ai résolu pour que je puisse garder lexical_cast <>
(J'ai trouvé cette page quand je cherchais un moyen moins nul :-)
Bravo, A.
la source
Cela a fonctionné pour moi:
la source
Essaye ça. Cette solution est un peu risquée. Il n'y a pas de chèques. La chaîne ne doit avoir que des valeurs hexadécimales et la longueur de la chaîne doit correspondre à la taille du type de retour. Mais pas besoin d'en-têtes supplémentaires.
Usage:
Remarque: la longueur de la chaîne doit être divisible par 2
la source