将前导“0x”的十六进制字符串转换为在 C++ 中签署空头?

发布于 2024-08-06 11:15:26 字数 706 浏览 4 评论 0原文

我找到了使用 strtol 将十六进制字符串转换为 signed int 的代码,但我找不到短 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(); 

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 piece of code :

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

My idea is to read a file with 2 bytes wide values (like 0xFFEE), convert it to signed int and write the result in an output file. Execution speed is not an issue.

I could find some ways to avoid the problem, but I'd like to use a "one line" solution, so maybe you can help for this :)

Edit : The files look like this :

0x0400
0x03fe
0x03fe
...

Edit : I already tried with the hex operator, but I still have to convert the string to an integer before doing so.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

青春如此纠结 2024-08-13 11:15:26

这应该很简单:

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

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 ...
}
别靠近我心 2024-08-13 11:15:26

您可能可以使用 stringtream 类的 >>带有六角操纵器的操作员。

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

羁绊已千年 2024-08-13 11:15:26

您是否考虑过使用带有“%hx”转换限定符的 sscanf?

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

堇色安年 2024-08-13 11:15:26
// 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
}
// 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
}
〆一缕阳光ご 2024-08-13 11:15:26

如果您确定可以信任 currentString.c_str() 中的数据,那么您也可以轻松地执行以下操作

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

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());
青衫负雪 2024-08-13 11:15:26

如果您知道数据始终采用这种格式,您难道不能这样做:

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

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"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文