Convert hex string (char []) to int?

前端 未结 13 936
栀梦
栀梦 2020-11-22 12:12

I have a char[] that contains a value such as \"0x1800785\" but the function I want to give the value to requires an int, how can I convert this to an int? I have searched a

相关标签:
13条回答
  • 2020-11-22 12:36

    This is a function to directly convert hexadecimal containing char array to an integer which needs no extra library:

    int hexadecimal2int(char *hdec) {
        int finalval = 0;
        while (*hdec) {
            
            int onebyte = *hdec++; 
            
            if (onebyte >= '0' && onebyte <= '9'){onebyte = onebyte - '0';}
            else if (onebyte >= 'a' && onebyte <='f') {onebyte = onebyte - 'a' + 10;}
            else if (onebyte >= 'A' && onebyte <='F') {onebyte = onebyte - 'A' + 10;}  
            
            finalval = (finalval << 4) | (onebyte & 0xF);
        }
        finalval = finalval - 524288;
        return finalval;
    }
    
    0 讨论(0)
  • 2020-11-22 12:44

    Use strtol if you have libc available like the top answer suggests. However if you like custom stuff or are on a microcontroller without libc or so, you may want a slightly optimized version without complex branching.

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

    The bit shifting magic boils down to: Just use the last 4 bits, but if it is an non digit, then also add 9.

    0 讨论(0)
  • 2020-11-22 12:44

    i have done a similar thing, think it might help u its actually working for me

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

    here i have only taken a string of 8 characters. if u want u can add similar logic for 'a' to 'f' to give their equivalent hex values,i haven't done that cause i didn't needed it.

    0 讨论(0)
  • 2020-11-22 12:48

    One quick & dirty solution:

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

    You have to be sure your input is correct, no validation included (one could say it is C). Good thing it is quite compact, it works with both 'A' to 'F' and 'a' to 'f'.

    The approach relies on the position of alphabet characters in the ASCII table, let's peek e.g. to Wikipedia (https://en.wikipedia.org/wiki/ASCII#/media/File:USASCII_code_chart.png). Long story short, the numbers are below the characters, so the numeric characters (0 to 9) are easily converted by subtracting the code for zero. The alphabetic characters (A to F) are read by zeroing other than last three bits (effectively making it work with either upper- or lowercase), subtracting one (because after the bit masking, the alphabet starts on position one) and adding ten (because A to F represent 10th to 15th value in hexadecimal code). Finally, we need to combine the two digits that form the lower and upper nibble of the encoded number.

    Here we go with same approach (with minor variations):

    #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;
    }
    
    0 讨论(0)
  • 2020-11-22 12:49

    So, after a while of searching, and finding out that strtol is quite slow, I've coded my own function. It only works for uppercase on letters, but adding lowercase functionality ain't a problem.

    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 because the hex we want to convert starts at offset 1, and 8 because it's the hex length.

    Speedtest (1.000.000 calls):

    strtol ~ 0.4400s
    hexToInt ~ 0.1100s
    
    0 讨论(0)
  • 2020-11-22 12:50

    Assuming you mean it's a string, how about strtol?

    0 讨论(0)
提交回复
热议问题