将带有前导“0x”的十六进制字符串转换为C ++中的signed short?

时间:2009-09-28 14:44:48

标签: c++ string hex int short

我找到了使用signed int将十六进制字符串转换为strtol的代码,但我找不到短整数(2字节)的内容。这是我的一段代码:

while (!sCurrentFile.eof() )
{
    getline (sCurrentFile,currentString);
    sOutputFile<<strtol(currentString.c_str(),NULL,16)<<endl;
}

我的想法是读取一个2字节宽值的文件(如0xFFEE),将其转换为signed int并将结果写入输出文件。执行速度不是问题。

我可以找到一些方法来避免这个问题,但我想使用“一线”解决方案,所以也许你可以为此提供帮助:)

编辑:文件如下所示:

0x0400
0x03fe
0x03fe
...

编辑:我已经尝试过使用十六进制运算符,但在执行此操作之前,我仍然需要将字符串转换为整数。

// This won't work as currentString is not an integer
myInt << std::hex << currentString.c_str(); 

6 个答案:

答案 0 :(得分:4)

这应该很简单:

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 (!sCurrentFile.eof() )
{
    getline (sCurrentFile,currentString);
    ... STUFF ...
}

这是因为当您阅读最后一行时,它会设置EOF。因此,当你循环然后读取最后一行之后的行时,getline()将失败,你将在上一次设置时对currentString中的内容执行STUFF。因此,您将在最后一行处理两次。

循环文件的正确方法是:

while (getline(sCurrentFile,currentString))
{
    // If the get fails then you have read past EOF and loop is not entered.
    ... STUFF ...
}

答案 1 :(得分:3)

您是否考虑过使用“%hx”转化限定符sscanf

答案 2 :(得分:3)

您可以使用stringtream课程的&gt;&gt;操作员使用六角操纵器。

答案 3 :(得分:0)

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

答案 4 :(得分:-1)

如果您确定可以从currentString.c_str()信任数据,那么您也可以轻松完成

myInt << std::hex << atoi(currentString.c_str());

答案 5 :(得分:-1)

如果您知道数据总是采用该格式,那么您不能只执行以下操作:

myInt << std::hex << currentString.c_str() +2; // skip the leading "0x"