Подтвердить что ты не робот

Преобразовать шестнадцатеричную строку (char []) в int?

У меня есть char [], который содержит значение, такое как "0x1800785", но для функции, которую я хочу предоставить для значения, требуется int, как я могу преобразовать это в int? Я искал вокруг, но не могу найти ответа. Спасибо.

4b9b3361

Ответ 1

Вы пробовали strtol()?

strtol - преобразовать строку в длинное целое

Пример:

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

В случае, если строковое представление числа начинается с префикса 0x, один должен должен использовать 0 в качестве базы:

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

(Можно также указать явную базу, такую ​​как 16, но я бы не рекомендовал вводить избыточность.)

Ответ 2

Что-то вроде этого может быть полезно:

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

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

Прочитайте man sscanf

Ответ 3

Или, если вы хотите иметь свою собственную реализацию, я написал эту быструю функцию в качестве примера:

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

Ответ 4

Предполагая, что вы имеете в виду строку, как насчет strtol?

Ответ 5

Попробуйте использовать блок кода, который работает для меня.

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

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

Выход:

value x: 820 - 2080

Ответ 6

Итак, после некоторого времени поиска и обнаружения того, что strtol довольно медленный, я кодировал свою собственную функцию. Он работает только для заглавных букв, но добавление строчных букв не является проблемой.

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

Использование:

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

1, потому что гекс, который мы хотим преобразовать, начинается со смещения 1, а 8, потому что это длина гекса.

Speedtest (1.000.000 звонков):

strtol ~ 0.4400s
hexToInt ~ 0.1100s

Ответ 7

Один быстрый & грязное решение:

// makes a number from two ascii hexa characters
int ahex2int(char a, char b){

    a = (a <= '9') ? a - '0' : (a & 0x7) + 9;
    b = (b <= '9') ? b - '0' : (b & 0x7) + 9;

    return (a << 4) + b;
}

Вы должны быть уверены, что введенные данные верны, проверка не включена (можно сказать, что это C). Хорошо, что он довольно компактный, он работает с буквами "A" - "F" и "a" - "f".

Подход основан на положении букв алфавита в таблице ASCII, например, давайте посмотрим. в Википедию (https://en.wikipedia.org/wiki/ASCII#/media/File:USASCII_code_chart.png). Короче говоря, цифры находятся ниже символов, поэтому числовые символы (от 0 до 9) легко конвертируются путем вычитания кода для нуля. Буквенные символы (от A до F) читаются путем обнуления, отличного от последних трех битов (эффективно заставляя его работать с upper- или строчными буквами), вычитания одного (потому что после маскировки битов алфавит начинается с первой позиции) и добавления десяти (потому что от A до F представляют 10-15 значение в шестнадцатеричном коде). Наконец, нам нужно объединить две цифры, которые образуют нижний и верхний кусочек закодированного числа.

Здесь мы идем с тем же подходом (с небольшими изменениями):

#include <stdio.h>

// takes a null-terminated string of hexa characters and tries to 
// convert it to numbers
long ahex2num(unsigned char *in){

    unsigned char *pin = in; // lets use pointer to loop through the string
    long out = 0;  // here we accumulate the result

    while(*pin != 0){
        out <<= 4; // we have one more input character, so 
                   // we shift the accumulated interim-result one order up
        out +=  (*pin < 'A') ? *pin & 0xF : (*pin & 0x7) + 9; // add the new nibble
        pin++; // go ahead
    }

    return out;
}

// main function will test our conversion fn
int main(void) {

    unsigned char str[] = "1800785";  // no 0x prefix, please
    long num;

    num = ahex2num(str);  // call the function

    printf("Input: %s\n",str);  // print input string
    printf("Output: %x\n",num);  // print the converted number back as hexa
    printf("Check: %ld = %ld \n",num,0x1800785);  // check the numeric values matches

    return 0;
}

Ответ 8

Я сделал librairy, чтобы сделать шестнадцатеричное/десятичное преобразование без использования stdio.h. Очень прост в использовании:

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

Перед первым преобразованием инициализируйте массив, используемый для преобразования, с помощью:

void init_hexdec ();

Здесь ссылка на github: https://github.com/kevmuret/libhex/

Ответ 9

Я сделал аналогичную вещь, думаю, что это может помочь он действительно работает для меня

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

здесь я взял только строку из 8 символов. если вы хотите, чтобы u мог добавить аналогичную логику для 'a' to 'f', чтобы дать свои эквивалентные шестнадцатеричные значения, я не сделал этого, потому что я не нуждался в этом.

Ответ 10

Используйте strtol если у вас есть libc, как strtol в верхнем ответе. Однако, если вам нравятся нестандартные вещи или вы используете микроконтроллер без libc или около того, вы можете захотеть слегка оптимизированную версию без сложных ветвлений.

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

Магия сдвига битов сводится к следующему: просто используйте последние 4 бита, но если это не цифра, то также добавьте 9.

Ответ 11

Используйте xtoi (stdlib.h). Строка имеет "0x" в качестве первых двух индексов, поэтому trim val [0] и val [1] выключен, отправив xtoi & val [2].

xtoi( &val[2] );

Ответ 12

Я знаю, что это действительно старый, но я думаю, что решения выглядели слишком сложными. Попробуйте это в VB:

Public Function HexToInt(sHEX as String) as long
Dim iLen as Integer
Dim i as Integer 
Dim SumValue as Long 
Dim iVal as long
Dim AscVal as long

    iLen = Len(sHEX)
    For i = 1 to Len(sHEX)
      AscVal = Asc(UCase(Mid$(sHEX, i,  1)))
      If AscVal >= 48 And AscVal  <= 57 Then
        iVal  = AscVal - 48
      ElseIf AscVal >= 65 And AscVal <= 70 Then
        iVal = AscVal - 55
      End If 
      SumValue = SumValue + iVal * 16 ^ (iLen- i)
    Next i 
    HexToInt  = SumValue
End Function