【问题标题】:Convert LPCTSTR HEXADECIMAL to BYTE in VS C++在 VS C++ 中将 LPCTSTR HEXADECIMAL 转换为 BYTE
【发布时间】:2018-10-31 15:20:28
【问题描述】:

我有以下函数支持将 LPCTSTR 转换为 BYTE ,但输入 str 目前仅支持数字。

void StrToByte2(LPCTSTR str, BYTE *dest)
{
    UINT count = _ttoi(str);
    BYTE buf[4] = { 0 };
    char string[10] = { 0 };
    sprintf_s(string, 10, "%04d", count);
    for (int i = 0; i < 4; ++i)
    {
        if ((string[i] >= '0') && (string[i] <= '9'))
            buf[i] = string[i] - '0';
    }
    dest[0] = (BYTE)(buf[0] << 4) | buf[1];
    dest[1] = (BYTE)(buf[2] << 4) | buf[3];
}

如果我在“1234”(任何数字)上调用此函数,dest 输出一些 12814,

struct st               
{
    byte    btID[2];
    int     nID;
};

PTR ptr(new st);
StrToByte2(strCode, ptr->btID);

但是当我在任何十六进制 ex A123 上调用此函数时,它总是输出 0000。

下面的函数用于将dest代码转换回str

CString Byte2ToStr(const byte* pbuf)
{
    CString str;
    str.Format(_T("%02X%02X"), pbuf[0], pbuf[1]);
    return str;
}

如何将 A123 转换为字节,然后返回 str 以显示 A123? 请帮忙!!

【问题讨论】:

  • 所以你希望函数能够处理hexa-decimal数字?
  • 顺便说一下,了解the standard character classification functions 可能是一个好的开始。更具体地说是isxdigitisdigit(以及例如toupper)。
  • "如果我在 "1234" (任何数字) 上调用此函数,dest 输出显示 1234" 这不是真的,你的函数不会那样做。首先,告诉我们您是否使用 Unicode(检查项目设置 -> 字符集)。描述您正在考虑的问题和解决方案。放置一个printf 函数来显示输出。我的猜测是您正在尝试convert hexadecimal string to bytes
  • 无论你做什么,union 都是未定义行为的前兆。看看this Q&A
  • 您使用的联合有一个很大的危险信号:它似乎在数组和WORD 变量之间尝试type punning。在 C++ 中,这是不允许的并导致 undefined behavior。在 C++ 中,您必须读取最后写入的联合成员。

标签: c++ string winapi visual-studio-2017 byte


【解决方案1】:
PTR ptr(new st);

这是 C++ 中的内存泄漏,因为new st 分配了内存,没有办法释放它。

UINT count = _ttoi(str);
...
sprintf_s(string, 10, "%04d", count);

这是将字符串转换为整数,然后将整数转换回字符串。它似乎没有真正的目的。

例如,"1234" 转换为 1234,然后又转换回 "1234"。但是"A123" 不是一个有效的数字,所以它被转换为0,然后转换为"0000"。所以这个方法失败了。您可以只使用原始字符串。

似乎这个函数试图将 2 个整数放入 1 个字节。这个只要每个值小于16或者0xF就可以了(不知道这可能有什么目的) 可以这样修复:

void StrToByte2(const wchar_t* str, BYTE *dest)
{
    int len = wcslen(str);
    if(len != 4)
        return; //handle error
    char buf[4] = { 0 };
    for(int i = 0; i < 4; ++i)
        if(str[i] >= L'0' && str[i] <= L'9')
            buf[i] = (BYTE)(str[i] - L'0');
    dest[0] = (buf[0] << 4) + buf[1];
    dest[1] = (buf[2] << 4) + buf[3];
}

CStringW Byte2_To_Str(BYTE *dest)
{
    CStringW str;
    str.AppendFormat(L"%X", 0xF & (dest[0] >> 4));
    str.AppendFormat(L"%X", 0xF & (dest[0]));
    str.AppendFormat(L"%X", 0xF & (dest[1] >> 4));
    str.AppendFormat(L"%X", 0xF & (dest[1]));
    return str;
}

int main()
{
    BYTE dest[2] = { 0 };
    StrToByte2(L"1234", dest);
    OutputDebugStringW(Byte2_To_Str(dest));
    OutputDebugStringW(L"\n");
    return 0;
}

如果字符串是十六进制,可以使用sscanf将每对字符转换为字节。

基本上,"1234" 更改为 12 34
"A123" 更改为 A1 23

bool hexstring_to_bytes(const wchar_t* str, BYTE *dest, int dest_size = 2)
{
    int len = wcslen(str);

    if((len / 2) > dest_size)
    {
        //error
        return false;
    }

    for(int i = 0; i < len / 2; i++)
    {
        int v;
        if(swscanf_s(str + i * 2, L"%2x", &v) != 1) 
            break;
        dest[i] = (unsigned char)v;
    }

    return true;
}

CStringW bytes_to_hexstring(const BYTE* bytes, int byte_size = 2)
{
    CString str;
    for(int i = 0; i < byte_size; i++)
        str.AppendFormat(L"%02X ", bytes[i] & 0xFF);
    return str;
}

int main()
{
    CStringW str;
    CStringW new_string;

    BYTE dest[2] = { 0 };

    str = L"1234";
    hexstring_to_bytes(str, dest);
    new_string = bytes_to_hexstring(dest);
    OutputDebugString(new_string);
    OutputDebugString(L"\n");

    str = L"A123";
    hexstring_to_bytes(str, dest);
    new_string = bytes_to_hexstring(dest);
    OutputDebugStringW(new_string);
    OutputDebugStringW(L"\n");

    return 0;
}

【讨论】:

  • 我建议将CString 替换为CStringW 以匹配字符串文字的类型。
  • @pushE 你想把 4 个字节放入 2 个字节吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-30
  • 1970-01-01
  • 2018-03-25
  • 1970-01-01
  • 2017-11-10
  • 2016-06-07
  • 2018-06-02
相关资源
最近更新 更多