我有一个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
我觉得答案可能很简单,但经过一些研究我尝试了上述内容并没有成功。由于我的想法已经不多了(我尝试过几乎没有类似的事情),我转向社区寻求帮助。
答案 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;
}
这就像一个相当黑客的解释,但它非常可靠。