Convert hexadecimal string with leading “0x” to signed short in C++?

前端 未结 6 806
孤城傲影
孤城傲影 2020-12-04 00:37

I found the code to convert a hexadecimal string into a signed int using strtol, but I can\'t find something for a short int (2 bytes). Here\' my p

相关标签:
6条回答
  • 2020-12-04 00:45
    // convert unsigned-integer to it's hexadecimal string represention
    // 0x12345678 -> '12345678'
    // N is BYTE/WORD/UINT/ULONGLONG
    // T is char or wchar_t
    template <class N, class T> inline T* UnsignedToHexStr(N    n             ,  // [i  ]
                                                           T*   pcStr         ,  // [i/o] filled with string
                                                           UINT nDigits       ,  // [i  ] number of digits in output string / 0 (auto)
                                                           bool bNullTerminate ) // [i  ] whether to add NULL termination
    {
        if ((N)-1 < (N)1)              // if type of N is floating-point / signed-integer
            if (::IsDebuggerPresent())
            {
                ::OutputDebugString(_T("UnsignedToHexStr: Incorrect type passed\n"));
                ::DebugBreak();
            }
    
        if (!nDigits)
            nDigits= GetUnsignedHexDigits(n);
    
        if (1 == sizeof(T))
        {
            const char _czIntHexConv[]= "0123456789ABCDEF";
            for (int i= nDigits-1; i>= 0; i--)
            {
                char* pLoc= (char*)&pcStr[i];
                *pLoc= _czIntHexConv[n & 0x0F];
                n >>= 4;
            }
        }
        else
        {
            const wchar_t _czIntHexConv[]= L"0123456789ABCDEF";
            for (int i= nDigits-1; i>= 0; i--)
            {
                wchar_t* pLoc= (wchar_t*)&pcStr[i];
                *pLoc= _czIntHexConv[n & 0x0F];
                n >>= 4;
            }
        }
    
        if (bNullTerminate)
            pcStr[nDigits]= 0;
    
        return pcStr;
    }
    
    
    
    // --------------------------------------------------------------------------
    // convert unsigned-integer in HEX string represention to it's numerical value
    // '1234' -> 0x1234
    // N is BYTE/WORD/UINT/ULONGLONG
    // T is char or wchar_t
    template <class N, class T> inline bool HexStrToUnsigned(const T* pczSrc                    ,
                                                             N&       n                         ,
                                                             bool     bSpecificTerminator= false,  // whether string should terminate with specific terminating char
                                                             T        cTerminator        = 0     ) // specific terminating char
    {
        n= 0;
    
        if (!pczSrc)
            return false;
    
        while ((32 == *pczSrc) || (9 == *pczSrc))
            pczSrc++;
    
        bool bLeadZeros= *pczSrc == _T('0');
        while (*pczSrc == _T('0')) // skip leading zeros
            pczSrc++;
    
        BYTE nMaxDigits= 2*sizeof(N);
        BYTE nDigits   = 0          ;
    
        while (true)
        {
            if ( (*pczSrc >= _T('0')) && (*pczSrc <= _T('9')))
            { if (nDigits==nMaxDigits) return false; n= (n<<4) + (*pczSrc-_T('0')   ); pczSrc++; nDigits++; continue; }
    
            if ( (*pczSrc >= _T('A')) && (*pczSrc <= _T('F')))
            { if (nDigits==nMaxDigits) return false; n= (n<<4) + (*pczSrc-_T('A')+10); pczSrc++; nDigits++; continue; }
    
            if ( (*pczSrc >= _T('a')) && (*pczSrc <= _T('f')))
            { if (nDigits==nMaxDigits) return false; n= (n<<4) + (*pczSrc-_T('a')+10); pczSrc++; nDigits++; continue; }
    
            if (bSpecificTerminator)
                if (*pczSrc != cTerminator)
                    return false;
    
            break;
        }
    
        return (nDigits>0) || bLeadZeros; // at least one digit
    }
    
    0 讨论(0)
  • 2020-12-04 00:54

    This should be simple:

    std::ifstream   file("DataFile");
    int             value;
    
    while(file >> std::hex >> value)  // Reads a hex string and converts it to an int.
    {
        std::cout << "Value: " << std::hex << value << "\n";
    }
    

    While we are talking about files:
    You should NOT do this:

    while (!sCurrentFile.eof() )
    {
        getline (sCurrentFile,currentString);
        ... STUFF ...
    }
    

    This is because when you read the last line it does NOT set the EOF. So when you loop around and then read the line after the last line, getline() will fail and you will be doing STUFF on what was in currentString from the last time it was set up. So in-effect you will processes the last line twice.

    The correct way to loop over a file is:

    while (getline(sCurrentFile,currentString))
    {
        // If the get fails then you have read past EOF and loop is not entered.
        ... STUFF ...
    }
    
    0 讨论(0)
  • 2020-12-04 00:55

    You can probably use stringtream class's >> operator with hex manipulator.

    0 讨论(0)
  • 2020-12-04 00:58

    If you're sure the data can be trusted from currentString.c_str(), then you could also easily do

    myInt << std::hex << atoi(currentString.c_str());
    
    0 讨论(0)
  • 2020-12-04 00:59

    Have you considered sscanf with the "%hx" conversion qualifier?

    0 讨论(0)
  • 2020-12-04 01:00

    If you know the data is always going to be in that format, couldn't you just do something like:

    myInt << std::hex << currentString.c_str() +2; // skip the leading "0x"
    
    0 讨论(0)
提交回复
热议问题