如何用十六进制格式化`unsigned char`数组的值?

时间:2017-12-12 01:18:31

标签: c++

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

显然,如果我直接尝试将字符数组用作字符串,我会被解释为ASCII(例如,它将被渲染为:“\xfê)Z +'\ x2”。理想情况下,我想显示原始十六进制值而不解释它们。

我曾尝试将其复制到字符串中,但尚未成功。我将展示我所尝试的内容以及我得到的结果:

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

我觉得答案可能很简单,但经过一些研究我尝试了上述内容并没有成功。由于我的想法已经不多了(我尝试过几乎没有类似的事情),我转向社区寻求帮助。

3 个答案:

答案 0 :(得分:3)

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

代码可以是:

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

请勿使用char *指针尝试此操作,这可能会导致未定义的行为。它依赖于index unsigned 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]);

答案 1 :(得分:3)

假设您想要表示为十六进制的任意字符,您只需使用以下完整测试程序中的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("\x3\x1\x4\x1\x5\x9\xff") << std::endl;
}

答案 2 :(得分:0)

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

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

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