web-dev-qa-db-fra.com

Convertit une chaîne hexagonale (char []) en int?

J'ai un caractère [] qui contient une valeur telle que "0x1800785" mais la fonction à laquelle je veux donner la valeur nécessite un int, comment puis-je la convertir en int? J'ai cherché autour mais je ne trouve pas de réponse. Merci.

69
kizyle502

Avez-vous essayé strtol()?

strtol - convertit une chaîne en un entier long

Exemple:

const char *hexstring = "abcdef0";
int number = (int)strtol(hexstring, NULL, 16);

Au cas où la représentation sous forme de chaîne du nombre commence par un préfixe 0x, un doit devrait utiliser 0 comme base:

const char *hexstring = "0xabcdef0";
int number = (int)strtol(hexstring, NULL, 0);

(Il est également possible de spécifier une base explicite telle que 16, mais je ne recommanderais pas l'introduction de la redondance.)

179
user529758

Quelque chose comme ça pourrait être utile:

char str[] = "0x1800785";
int num;

sscanf(str, "%x", &num);
printf("0x%x %i\n", num, num); 

Lire man sscanf

19
saxi

En supposant que vous pensiez que c'est une chaîne, que diriez-vous de strtol ?

9
James McLaughlin

Ou si vous voulez avoir votre propre implémentation, j'ai écrit cette fonction rapide à titre d'exemple:

/**
 * hex2int
 * take a hex string and convert it to a 32bit number (max 8 hex digits)
 */
uint32_t hex2int(char *hex) {
    uint32_t val = 0;
    while (*hex) {
        // get current character then increment
        uint8_t byte = *hex++; 
        // transform hex character to the 4bit equivalent number, using the ascii table indexes
        if (byte >= '0' && byte <= '9') byte = byte - '0';
        else if (byte >= 'a' && byte <='f') byte = byte - 'a' + 10;
        else if (byte >= 'A' && byte <='F') byte = byte - 'A' + 10;    
        // shift 4 to make space for new digit, and add the 4 bits of the new digit 
        val = (val << 4) | (byte & 0xF);
    }
    return val;
}
9
radhoo

Essayez ci-dessous bloc de code, cela fonctionne pour moi.

char *p = "0x820";
uint16_t intVal;
sscanf(p, "%x", &intVal);

printf("value x: %x - %d", intVal, intVal);

La sortie est:

value x: 820 - 2080
4
Dig The Code

Ainsi, après un certain temps de recherche et découvrant que strtol est assez lent, j'ai codé ma propre fonction. Cela ne fonctionne que pour les lettres majuscules, mais l'ajout de fonctionnalités minuscules n'est pas un problème.

int hexToInt(PCHAR _hex, int offset = 0, int size = 6)
{
    int _result = 0;
    DWORD _resultPtr = reinterpret_cast<DWORD>(&_result);
    for(int i=0;i<size;i+=2)
    {
        int _multiplierFirstValue = 0, _addonSecondValue = 0;

        char _firstChar = _hex[offset + i];
        if(_firstChar >= 0x30 && _firstChar <= 0x39)
            _multiplierFirstValue = _firstChar - 0x30;
        else if(_firstChar >= 0x41 && _firstChar <= 0x46)
            _multiplierFirstValue = 10 + (_firstChar - 0x41);

        char _secndChar = _hex[offset + i + 1];
        if(_secndChar >= 0x30 && _secndChar <= 0x39)
            _addonSecondValue = _secndChar - 0x30;
        else if(_secndChar >= 0x41 && _secndChar <= 0x46)
            _addonSecondValue = 10 + (_secndChar - 0x41);

        *(BYTE *)(_resultPtr + (size / 2) - (i / 2) - 1) = (BYTE)(_multiplierFirstValue * 16 + _addonSecondValue);
    }
    return _result;
}

Usage:

char *someHex = "#CCFF00FF";
int hexDevalue = hexToInt(someHex, 1, 8);

1 parce que l'hex que nous voulons convertir commence au décalage 1 et 8 parce que c'est la longueur de l'hex.

Test rapide (1.000.000 appels):

strtol ~ 0.4400s
hexToInt ~ 0.1100s
3
mexikanoZ

Utilisez strtol si vous avez la libc disponible, comme le suggère la réponse du haut. Toutefois, si vous aimez les éléments personnalisés ou si vous utilisez un microcontrôleur sans libc ou autre, vous pouvez choisir une version légèrement optimisée sans ramification complexe.

#include <inttypes.h>


/**
 * xtou64
 * Take a hex string and convert it to a 64bit number (max 16 hex digits).
 * The string must only contain digits and valid hex characters.
 */
uint64_t xtou64(const char *str)
{
    uint64_t res = 0;
    char c;

    while ((c = *str++)) {
        char v = (c & 0xF) + (c >> 6) | ((c >> 3) & 0x8);
        res = (res << 4) | (uint64_t) v;
    }

    return res;
} 

La magie du décalage des bits se résume à: Utilisez simplement les 4 derniers bits, mais s'il s'agit d'un nombre non numérique, ajoutez également 9.

0
LimeRed

j'ai fait la même chose, je pense que cela pourrait vous aider

int main(){ int co[8],i;char ch[8];printf("please enter the string:");scanf("%s",ch);for(i=0;i<=7;i++){if((ch[i]>='A')&&(ch[i]<='F')){co[i]=(unsigned int)ch[i]-'A'+10;}else if((ch[i]>='0')&&(ch[i]<='9')){co[i]=(unsigned int)ch[i]-'0'+0;}}

ici, je n'ai pris qu'une chaîne de 8 caractères ... Si vous voulez, vous pouvez ajouter une logique similaire pour "a" à "f" pour donner leurs valeurs hex équivalentes, je ne l'ai pas fait car je n'en avais pas besoin . 

0
sairam singh

J'ai créé une librairie pour effectuer une conversion hexadécimale/décimale sans utiliser stdio.h. Très simple à utiliser:

unsigned hexdec (const char *hex, const int s_hex);

Avant la première conversion, initialisez le tableau utilisé pour la conversion avec:

void init_hexdec ();

Voici le lien sur github: https://github.com/kevmuret/libhex/

0
kevmuret