3

我找到了将十六进制字符串转换为signed intusing的代码strtol,但我找不到短 int (2字节)的东西。这是我的一段代码:

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

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

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

编辑:文件如下所示:

0x0400
0x03fe
0x03fe
...

编辑:我已经尝试过使用十六进制运算符,但在这样做之前我仍然必须将字符串转换为整数。

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

6 回答 6

5

这应该很简单:

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 ...
}
于 2009-09-28T16:39:00.723 回答
4

您可能可以将stringtream类的 >> 运算符与十六进制操纵器一起使用。

于 2009-09-28T14:51:40.690 回答
3

您是否考虑sscanf过“%hx”转换限定符?

于 2009-09-28T14:51:06.013 回答
1
// 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
}
于 2009-09-28T16:55:42.180 回答
-1

如果您知道数据总是采用这种格式,您就不能这样做:

myInt << std::hex << currentString.c_str() +2; // skip the leading "0x"
于 2009-09-28T15:31:55.663 回答
-1

如果您确定可以信任数据currentString.c_str(),那么您也可以轻松地做到

myInt << std::hex << atoi(currentString.c_str());
于 2009-09-28T15:14:08.503 回答