如何以十六进制的形式打印字节?

时间:2022-10-06 16:43:17

I know in C# you can use String.Format method. But how do you do this in C++? Is there a function that allows me to convert a byte to a Hex?? Just need to convert a 8 byte long data to Hex, how do I do that?

我知道在c#中你可以使用字符串。格式的方法。但是如何用c++实现呢?有没有一个函数可以让我把一个字节转换成十六进制?只需要将8字节长的数据转换为十六进制,我怎么做呢?

6 个解决方案

#1


28  

Well you can convert one byte (unsigned char) at a time into a array like so

你可以一次将一个字节(无符号字符)转换成这样的数组。

char buffer [17];
buffer[16] = 0;
for(j = 0; j < 8; j++)
    sprintf(&buffer[2*j], "%02X", data[j]);

#2


51  

If you want to use C++ streams rather than C functions, you can do the following:

如果您想使用c++流而不是C函数,您可以执行以下操作:

    int ar[] = { 20, 30, 40, 50, 60, 70, 80, 90 };
    const int siz_ar = sizeof(ar) / sizeof(int);

    for (int i = 0; i < siz_ar; ++i)
        cout << ar[i] << " ";
    cout << endl;

    for (int i = 0; i < siz_ar; ++i)
        cout << hex << setfill('0') << setw(2) << ar[i] << " ";
    cout << endl;

Very simple.

非常简单。

Output:

输出:

20 30 40 50 60 70 80 90
14 1e 28 32 3c 46 50 5a 

#3


8  

C:

C:

static void print_buf(const char *title, const unsigned char *buf, size_t buf_len)
{
    size_t i = 0;
    fprintf(stdout, "%s\n", title);
    for(i = 0; i < buf_len; ++i)
    fprintf(stdout, "%02X%s", buf[i],
             ( i + 1 ) % 16 == 0 ? "\r\n" : " " );

}

C++:

c++:

void print_bytes(std::ostream& out, const char *title, const unsigned char *data, size_t dataLen, bool format = true) {
    out << title << std::endl;
    out << std::setfill('0');
    for(size_t i = 0; i < dataLen; ++i) {
        out << std::hex << std::setw(2) << (int)data[i];
        if (format) {
            out << (((i + 1) % 16 == 0) ? "\n" : " ");
        }
    }
    out << std::endl;
}

#4


3  

This is a modified version of the Nibble to Hex method

这是对十六进制方法的修改版本

void hexArrayToStr(unsigned char* info, unsigned int infoLength, char **buffer) {
    const char* pszNibbleToHex = {"0123456789ABCDEF"};
    int nNibble, i;
    if (infoLength > 0) {
        if (info != NULL) {
            *buffer = (char *) malloc((infoLength * 2) + 1);
            buffer[0][(infoLength * 2)] = 0;
            for (i = 0; i < infoLength; i++) {
                nNibble = info[i] >> 4;
                buffer[0][2 * i] = pszNibbleToHex[nNibble];
                nNibble = info[i] & 0x0F;
                buffer[0][2 * i + 1] = pszNibbleToHex[nNibble];
            }
        } else {
            *buffer = NULL;
        }
    } else {
        *buffer = NULL;
    }
}

#5


3  

Printing arbitrary structures in modern C++

All answers so far only tell you how to print an array of integers, but we can also print any arbitrary structure, given that we know its size. The example below creates such structure and iterates a pointer through its bytes, printing them to the output:

到目前为止,所有的答案都只告诉您如何打印一个整数数组,但是我们也可以打印任意的结构,因为我们知道它的大小。下面的示例创建了这样的结构,并通过其字节迭代指针,将其打印到输出:

#include <iostream>
#include <iomanip>
#include <cstring>

using std::cout;
using std::endl;
using std::hex;
using std::setfill;
using std::setw;

using u64 = unsigned long long;
using u16 = unsigned short;
using f64 = double;

struct Header {
    u16 version;
    u16 msgSize;
};

struct Example {
    Header header;
    u64 someId;
    u64 anotherId;
    bool isFoo;
    bool isBar;
    f64 floatingPointValue;
};

int main () {
    Example example;
    // fill with zeros so padding regions don't contain garbage
    memset(&example, 0, sizeof(Example));
    example.header.version = 5;
    example.header.msgSize = sizeof(Example) - sizeof(Header);
    example.someId = 0x1234;
    example.anotherId = 0x5678;
    example.isFoo = true;
    example.isBar = true;
    example.floatingPointValue = 1.1;

    cout << hex << setfill('0');  // needs to be set only once
    auto *ptr = reinterpret_cast<unsigned char *>(&example);
    for (int i = 0; i < sizeof(Example); i++, ptr++) {
        if (i % sizeof(u64) == 0) {
            cout << endl;
        }
        cout << setw(2) << static_cast<unsigned>(*ptr) << " ";
    }

    return 0;
}

And here's the output:

这是输出:

05 00 24 00 00 00 00 00 
34 12 00 00 00 00 00 00 
78 56 00 00 00 00 00 00 
01 01 00 00 00 00 00 00 
9a 99 99 99 99 99 f1 3f

Notice this example also illustrates memory alignment working. We see version occupying 2 bytes (05 00), followed by msgSize with 2 more bytes (24 00) and then 4 bytes of padding, after which comes someId (34 12 00 00 00 00 00 00) and anotherId (78 56 00 00 00 00 00 00). Then isFoo, which occupies 1 byte (01) and isBar, another byte (01), followed by 6 bytes of padding, finally ending with the IEEE 754 standard representation of the double field floatingPointValue.

请注意,这个示例还演示了内存对齐工作。我们看到版本占用了2个字节(05 00),然后是msgSize(24 00)和4个字节的填充,然后是一些id(34 12 00 00 00 00 00 00 00 00 00 00)和其他id(78 56 00 00 00 00 00 00 00 00 00)。然后isFoo占用1字节(01),isBar占用另一个字节(01),然后是6字节的填充,最后以双字段floatingPointValue的IEEE 754标准表示结束。

Also notice that all values are represented as little endian (least significant bytes come first), since this was compiled and run on an Intel platform.

还要注意,所有值都表示为小endian(最不重要的字节优先),因为它是在Intel平台上编译和运行的。

#6


1  

I don't know of a better way than:

我不知道有什么比:

unsigned char byData[xxx]; 

int nLength = sizeof(byData) * 2;
char *pBuffer = new char[nLength + 1];
pBuffer[nLength] = 0;
for (int i = 0; i < sizeof(byData); i++)
{
    sprintf(pBuffer[2 * i], "%02X", byData[i]);
}

You can speed it up by using a Nibble to Hex method

您可以通过使用对十六进制方法的略读来加快速度

unsigned char byData[xxx];

const char szNibbleToHex = { "0123456789ABCDEF" };

int nLength = sizeof(byData) * 2;
char *pBuffer = new char[nLength + 1];
pBuffer[nLength] = 0;
for (int i = 0; i < sizeof(byData); i++)
{
    // divide by 16
    int nNibble = byData[i] >> 4;
    pBuffer[2 * i]  = pszNibbleToHex[nNibble];

    nNibble = byData[i] & 0x0F;
    pBuffer[2 * i + 1]  = pszNibbleToHex[nNibble];

}

#1


28  

Well you can convert one byte (unsigned char) at a time into a array like so

你可以一次将一个字节(无符号字符)转换成这样的数组。

char buffer [17];
buffer[16] = 0;
for(j = 0; j < 8; j++)
    sprintf(&buffer[2*j], "%02X", data[j]);

#2


51  

If you want to use C++ streams rather than C functions, you can do the following:

如果您想使用c++流而不是C函数,您可以执行以下操作:

    int ar[] = { 20, 30, 40, 50, 60, 70, 80, 90 };
    const int siz_ar = sizeof(ar) / sizeof(int);

    for (int i = 0; i < siz_ar; ++i)
        cout << ar[i] << " ";
    cout << endl;

    for (int i = 0; i < siz_ar; ++i)
        cout << hex << setfill('0') << setw(2) << ar[i] << " ";
    cout << endl;

Very simple.

非常简单。

Output:

输出:

20 30 40 50 60 70 80 90
14 1e 28 32 3c 46 50 5a 

#3


8  

C:

C:

static void print_buf(const char *title, const unsigned char *buf, size_t buf_len)
{
    size_t i = 0;
    fprintf(stdout, "%s\n", title);
    for(i = 0; i < buf_len; ++i)
    fprintf(stdout, "%02X%s", buf[i],
             ( i + 1 ) % 16 == 0 ? "\r\n" : " " );

}

C++:

c++:

void print_bytes(std::ostream& out, const char *title, const unsigned char *data, size_t dataLen, bool format = true) {
    out << title << std::endl;
    out << std::setfill('0');
    for(size_t i = 0; i < dataLen; ++i) {
        out << std::hex << std::setw(2) << (int)data[i];
        if (format) {
            out << (((i + 1) % 16 == 0) ? "\n" : " ");
        }
    }
    out << std::endl;
}

#4


3  

This is a modified version of the Nibble to Hex method

这是对十六进制方法的修改版本

void hexArrayToStr(unsigned char* info, unsigned int infoLength, char **buffer) {
    const char* pszNibbleToHex = {"0123456789ABCDEF"};
    int nNibble, i;
    if (infoLength > 0) {
        if (info != NULL) {
            *buffer = (char *) malloc((infoLength * 2) + 1);
            buffer[0][(infoLength * 2)] = 0;
            for (i = 0; i < infoLength; i++) {
                nNibble = info[i] >> 4;
                buffer[0][2 * i] = pszNibbleToHex[nNibble];
                nNibble = info[i] & 0x0F;
                buffer[0][2 * i + 1] = pszNibbleToHex[nNibble];
            }
        } else {
            *buffer = NULL;
        }
    } else {
        *buffer = NULL;
    }
}

#5


3  

Printing arbitrary structures in modern C++

All answers so far only tell you how to print an array of integers, but we can also print any arbitrary structure, given that we know its size. The example below creates such structure and iterates a pointer through its bytes, printing them to the output:

到目前为止,所有的答案都只告诉您如何打印一个整数数组,但是我们也可以打印任意的结构,因为我们知道它的大小。下面的示例创建了这样的结构,并通过其字节迭代指针,将其打印到输出:

#include <iostream>
#include <iomanip>
#include <cstring>

using std::cout;
using std::endl;
using std::hex;
using std::setfill;
using std::setw;

using u64 = unsigned long long;
using u16 = unsigned short;
using f64 = double;

struct Header {
    u16 version;
    u16 msgSize;
};

struct Example {
    Header header;
    u64 someId;
    u64 anotherId;
    bool isFoo;
    bool isBar;
    f64 floatingPointValue;
};

int main () {
    Example example;
    // fill with zeros so padding regions don't contain garbage
    memset(&example, 0, sizeof(Example));
    example.header.version = 5;
    example.header.msgSize = sizeof(Example) - sizeof(Header);
    example.someId = 0x1234;
    example.anotherId = 0x5678;
    example.isFoo = true;
    example.isBar = true;
    example.floatingPointValue = 1.1;

    cout << hex << setfill('0');  // needs to be set only once
    auto *ptr = reinterpret_cast<unsigned char *>(&example);
    for (int i = 0; i < sizeof(Example); i++, ptr++) {
        if (i % sizeof(u64) == 0) {
            cout << endl;
        }
        cout << setw(2) << static_cast<unsigned>(*ptr) << " ";
    }

    return 0;
}

And here's the output:

这是输出:

05 00 24 00 00 00 00 00 
34 12 00 00 00 00 00 00 
78 56 00 00 00 00 00 00 
01 01 00 00 00 00 00 00 
9a 99 99 99 99 99 f1 3f

Notice this example also illustrates memory alignment working. We see version occupying 2 bytes (05 00), followed by msgSize with 2 more bytes (24 00) and then 4 bytes of padding, after which comes someId (34 12 00 00 00 00 00 00) and anotherId (78 56 00 00 00 00 00 00). Then isFoo, which occupies 1 byte (01) and isBar, another byte (01), followed by 6 bytes of padding, finally ending with the IEEE 754 standard representation of the double field floatingPointValue.

请注意,这个示例还演示了内存对齐工作。我们看到版本占用了2个字节(05 00),然后是msgSize(24 00)和4个字节的填充,然后是一些id(34 12 00 00 00 00 00 00 00 00 00 00)和其他id(78 56 00 00 00 00 00 00 00 00 00)。然后isFoo占用1字节(01),isBar占用另一个字节(01),然后是6字节的填充,最后以双字段floatingPointValue的IEEE 754标准表示结束。

Also notice that all values are represented as little endian (least significant bytes come first), since this was compiled and run on an Intel platform.

还要注意,所有值都表示为小endian(最不重要的字节优先),因为它是在Intel平台上编译和运行的。

#6


1  

I don't know of a better way than:

我不知道有什么比:

unsigned char byData[xxx]; 

int nLength = sizeof(byData) * 2;
char *pBuffer = new char[nLength + 1];
pBuffer[nLength] = 0;
for (int i = 0; i < sizeof(byData); i++)
{
    sprintf(pBuffer[2 * i], "%02X", byData[i]);
}

You can speed it up by using a Nibble to Hex method

您可以通过使用对十六进制方法的略读来加快速度

unsigned char byData[xxx];

const char szNibbleToHex = { "0123456789ABCDEF" };

int nLength = sizeof(byData) * 2;
char *pBuffer = new char[nLength + 1];
pBuffer[nLength] = 0;
for (int i = 0; i < sizeof(byData); i++)
{
    // divide by 16
    int nNibble = byData[i] >> 4;
    pBuffer[2 * i]  = pszNibbleToHex[nNibble];

    nNibble = byData[i] & 0x0F;
    pBuffer[2 * i + 1]  = pszNibbleToHex[nNibble];

}