C++ convert hex string to signed integer

前端 未结 9 1890
耶瑟儿~
耶瑟儿~ 2020-11-22 03:08

I want to convert a hex string to a 32 bit signed integer in C++.

So, for example, I have the hex string \"fffefffe\". The binary representation of this is 111111

相关标签:
9条回答
  • 2020-11-22 03:22

    Try this. This solution is a bit risky. There are no checks. The string must only have hex values and the string length must match the return type size. But no need for extra headers.

    char hextob(char ch)
    {
        if (ch >= '0' && ch <= '9') return ch - '0';
        if (ch >= 'A' && ch <= 'F') return ch - 'A' + 10;
        if (ch >= 'a' && ch <= 'f') return ch - 'a' + 10;
        return 0;
    }
    template<typename T>
    T hextot(char* hex)
    {
        T value = 0;
        for (size_t i = 0; i < sizeof(T)*2; ++i)
            value |= hextob(hex[i]) << (8*sizeof(T)-4*(i+1));
        return value;
    };
    

    Usage:

    int main()
    {
        char str[4] = {'f','f','f','f'};
        std::cout << hextot<int16_t>(str)  << "\n";
    }
    

    Note: the length of the string must be divisible by 2

    0 讨论(0)
  • 2020-11-22 03:25

    Andy Buchanan, as far as sticking to C++ goes, I liked yours, but I have a few mods:

    template <typename ElemT>
    struct HexTo {
        ElemT value;
        operator ElemT() const {return value;}
        friend std::istream& operator>>(std::istream& in, HexTo& out) {
            in >> std::hex >> out.value;
            return in;
        }
    };
    

    Used like

    uint32_t value = boost::lexical_cast<HexTo<uint32_t> >("0x2a");
    

    That way you don't need one impl per int type.

    0 讨论(0)
  • 2020-11-22 03:33

    Working example with strtoul will be:

    #include <cstdlib>
    #include <iostream>
    using namespace std;
    
    int main() { 
        string s = "fffefffe";
        char * p;
        long n = strtoul( s.c_str(), & p, 16 ); 
        if ( * p != 0 ) {  
            cout << "not a number" << endl;
        }    else {  
            cout << n << endl;
        }
    }
    

    strtol converts string to long. On my computer numeric_limits<long>::max() gives 0x7fffffff. Obviously that 0xfffefffe is greater than 0x7fffffff. So strtol returns MAX_LONG instead of wanted value. strtoul converts string to unsigned long that's why no overflow in this case.

    Ok, strtol is considering input string not as 32-bit signed integer before convertation. Funny sample with strtol:

    #include <cstdlib>
    #include <iostream>
    using namespace std;
    
    int main() { 
        string s = "-0x10002";
        char * p;
        long n = strtol( s.c_str(), & p, 16 ); 
        if ( * p != 0 ) {  
            cout << "not a number" << endl;
        }    else {  
            cout << n << endl;
        }
    }
    

    The code above prints -65538 in console.

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