how - print bytes in c++




How do I print bytes as hexadecimal? (4)

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?


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.

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.


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++:

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

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

    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 

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




data-conversion