我如何格式化十六进制中“未签名char”阵列的值

How do I format the values of an array of `unsigned char` in hexadecimal?

本文关键字:char 未签名 阵列 格式化 十六进制      更新时间:2023-10-16

我有一个无符号字符的数组,其中包含十六进制值。我想在日志中显示它,为了做到它,我需要将其转换为字符串。

显然,如果我直接尝试将字符阵列用作字符串,我会像ASCII(例如,它将呈现为:" xfê)z ’ x2"一样被解释为gibberish。理想情况下,我想展示原始的十六进制值,而不会被解释。

我试图将其复制到字符串中,但没有成功。我将介绍我尝试过的东西以及得到的结果:

//My starting data type is unsigned char *
unsigned char* index = Block_data.Index;
//I convert it to const char* since most functions I could find for this type of
//conversion require a const char *, if this step can be avoided: I will do that
const char* indexc1 = reinterpret_cast<const char*>(index);
char outVal[9]; //allocate target buffer space
sprintf_s(outVal, "%9x", indexc1); //copy to target. This manages to copy the 
                                 // address of indexc1 and not its contents
sprintf_s(outVal, "%9x", *indexc1); //This gets one character from the 
                                  // address
sscanf_s(indexc1, "%9x", outVal); //This gets empty string

我觉得答案可能很简单,但是经过一些研究,我尝试了上述并没有成功。由于我用尽了想法(我尝试了几种类似的事情),所以我向社区寻求帮助。

您的问题不是很清楚,但是我假设您想在十六进制中构建一个字符串,即index指向的前四个字节的值。

代码可能是:

char outVal[9];
sprintf(outVal, "%02X%02X%02X%02X", index[0], index[1], index[2], index[3]);

不要使用char *指针尝试,这可能导致不确定的行为。它依赖于indexunsigned char *

如果要打印更多字节,则可以切换到循环,例如:

std::vector<char> outVal( 2 * len + 1 );
for (size_t i = 0; i < len; ++i)
    sprintf(&outVal[i * 2], "%02X", index[i]);
// OutputDebugString(&outVal[0]);

假设您想要表示为十六进制的任意字符,则可以在以下完整的测试程序中使用makeString()appendChar()

#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <cstring>
// Append a single character as two-digit hex string.
void appendChar(std::stringstream &ss, const char *pref, const char ch) {
    ss  << pref
        << std::setfill('0')
        << std::setw(2)
        << std::hex
        << static_cast<unsigned int>(ch & 0xff);
}
// Construct a hex string from buffer.
std::string makeString(const char * const buff, size_t slen = 0) {
    std::stringstream ss;
    // Zero-length means C-style string.
    if (slen == 0)
        slen = strlen(buff);
    // Process each byte in character array.
    if (slen > 0) {
        appendChar(ss, "", buff[0]);
        for (size_t i = 1; i < slen; ++i)
            appendChar(ss, " ", buff[i]);
    }
    return ss.str();
}
// Rudimentary test code.
int main() {
    std::cout << makeString("hello", 4) << std::endl;
    std::cout << makeString("x3x1x4x1x5x9xff") << std::endl;
}

在更高级别上做到这一点可能并不难(如果不是性能密集型应用程序):

std::string hexToString(unsigned char c)
{
    std::string res = "";
    if (c >= 0xF0)
    {
        res += "F";
        c -= 0xF0;
    }
    else if (c >= 0xE0)
    {
        res += "E";
        c -= 0xE0;
    }
    else if (c >= 0xD0)
    {
        res += "D";
        c -= 0xD0;
    }
    else if (c >= 0xC0)
    {
        res += "C";
        c -= 0xC0;
    }
    else if (c >= 0xB0)
    {
        res += "B";
        c -= 0xB0;
    }
    else if (c >= 0xA0)
    {
        res += "A";
        c -= 0xA0;
    }
    else if (c >= 0x90)
    {
        res += "9";
        c -= 0x90;
    }
    else if (c >= 0x80)
    {
        res += "8";
        c -= 0x80;
    }
    else if (c >= 0x70)
    {
        res += "7";
        c -= 0x70;
    }
    else if (c >= 0x60)
    {
        res += "6";
        c -= 0x60;
    }
    else if (c >= 0x50)
    {
        res += "5";
        c -= 0x50;
    }
    else if (c >= 0x40)
    {
        res += "4";
        c -= 0x40;
    }
    else if (c >= 0x30)
    {
        res += "3";
        c -= 0x30;
    }
    else if (c >= 0x20)
    {
        res += "2";
        c -= 0x20;
    }
    else if (c >= 0x10)
    {
        res += "1";
        c -= 0x10;
    }
    else
    {
        res += "0";
    }

    if (c >= 0xF)
    {
        res += "F";
        c -= 0xF;
    }
    else if (c >= 0xE)
    {
        res += "E";
        c -= 0xE;
    }
    else if (c >= 0xD)
    {
        res += "D";
        c -= 0xD;
    }
    else if (c >= 0xC)
    {
        res += "C";
        c -= 0xC;
    }
    else if (c >= 0xB)
    {
        res += "B";
        c -= 0xB;
    }
    else if (c >= 0xA)
    {
        res += "A";
        c -= 0xA0;
    }
    else if (c >= 0x9)
    {
        res += "9";
        c -= 0x90;
    }
    else if (c >= 0x8)
    {
        res += "8";
        c -= 0x8;
    }
    else if (c >= 0x7)
    {
        res += "7";
        c -= 0x7;
    }
    else if (c >= 0x6)
    {
        res += "6";
        c -= 0x6;
    }
    else if (c >= 0x5)
    {
        res += "5";
        c -= 0x5;
    }
    else if (c >= 0x4)
    {
        res += "4";
        c -= 0x4;
    }
    else if (c >= 0x3)
    {
        res += "3";
        c -= 0x3;
    }
    else if (c >= 0x2)
    {
        res += "2";
        c -= 0x2;
    }
    else if (c >= 0x1)
    {
        res += "1";
        c -= 0x10;
    }
    else res += "0";
    return res;
}

这就像一个相当黑的解释,但非常可靠。