Предоставлено моей библиотекой полезных фрагментов, вот решение на C, в комплекте с тестовым набором и предоставлением как шестнадцатеричных, так и ASCII-данных:
#include <stdio.h>
void hexDump (char *desc, void *addr, int len) {
int i;
unsigned char buff[17]; // stores the ASCII data
unsigned char *pc = addr; // cast to make the code cleaner.
// Output description if given.
if (desc != NULL)
printf ("%s:\n", desc);
// Process every byte in the data.
for (i = 0; i < len; i++) {
// Multiple of 16 means new line (with line offset).
if ((i % 16) == 0) {
// Just don't print ASCII for the zeroth line.
if (i != 0)
printf (" %s\n", buff);
// Output the offset.
printf (" %04x ", i);
}
// Now the hex code for the specific character.
printf (" %02x", pc[i]);
// And store a printable ASCII character for later.
if ((pc[i] < 0x20) || (pc[i] > 0x7e))
buff[i % 16] = '.';
else
buff[i % 16] = pc[i];
buff[(i % 16) + 1] = '\0';
}
// Pad out last line if not exactly 16 characters.
while ((i % 16) != 0) {
printf (" ");
i++;
}
// And print the final ASCII bit.
printf (" %s\n", buff);
}
int main (int argc, char *argv[]) {
double d1 = 234.5;
char s1[] = "a 15char string";
char s2[] = "This is a slightly longer string";
hexDump ("d1", &d1, sizeof d1);
hexDump ("s1", &s1, sizeof s1);
hexDump ("s2", &s2, sizeof s2);
return 0;
}
Вывод в моей системе:
d1:
0000 00 00 00 00 00 50 6d 40 .....Pm@
s1:
0000 61 20 31 35 63 68 61 72 20 73 74 72 69 6e 67 00 a 15char string.
s2:
0000 54 68 69 73 20 69 73 20 61 20 73 6c 69 67 68 74 This is a slight
0010 6c 79 20 6c 6f 6e 67 65 72 20 73 74 72 69 6e 67 ly longer string
0020 00 .
Поскольку этот вопрос также помечен как C ++, вот версия iostream для сравнения. Даже если вы не являетесь поклонником iostreams, он все равно подходит, если вы уже используете их. Возможность использовать hexdump(any_obj)
тоже хороша, но, конечно, это можно сделать просто с помощью шаблона делегирующей функции, аналогичного ctor.
#include <iomanip>
#include <ostream>
#include <string>
struct hexdump {
void const* data;
int len;
hexdump(void const* data, int len) : data(data), len(len) {}
template<class T>
hexdump(T const& v) : data(&v), len(sizeof v) {}
friend
std::ostream& operator<<(std::ostream& s, hexdump const& v) {
// don't change formatting for s
std::ostream out (s.rdbuf());
out << std::hex << std::setfill('0');
unsigned char const* pc = reinterpret_cast<unsigned char const*>(v.data);
std::string buf;
buf.reserve(17); // premature optimization
int i;
for (i = 0; i < v.len; ++i, ++pc) {
if ((i % 16) == 0) {
if (i) {
out << " " << buf << '\n';
buf.clear();
}
out << " " << std::setw(4) << i << ' ';
}
out << ' ' << std::setw(2) << unsigned(*pc);
buf += (0x20 <= *pc && *pc <= 0x7e) ? *pc : '.';
}
if (i % 16) {
char const* spaces16x3 = " ";
out << &spaces16x3[3 * (i % 16)];
}
out << " " << buf << '\n';
return s;
}
};
int main() {
std::cout << "double:\n" << hexdump(234.5);
std::cout << "string 1:\n" << hexdump("a 15char string");
std::cout << "string 2:\n" << hexdump("This is a slightly longer string");
return 0;
}