Hex dump: Difference between revisions

Content added Content deleted
m (→‎{{header|Julia}}: add final count)
(Added C solution)
Line 64: Line 64:
Other hexdump/xxd features and a command line interface to your program are optional.
Other hexdump/xxd features and a command line interface to your program are optional.



=={{header|C}}==
<syntaxhighlight lang="c">#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

#define BYTES_HEX 16
#define BYTES_BIN 6

static void print_hex(const char* data, long count) {
long i = 0;
for (; i < count; ++i) {
if (i % 8 == 0)
putchar(' ');
printf(" %02x", (unsigned char)data[i]);
}
for (; i < BYTES_HEX; ++i) {
if (i % 8 == 0)
putchar(' ');
printf(" ");
}
}

static void print_binary(const char* data, long count) {
long i = 0;
putchar(' ');
for (; i < count; ++i) {
unsigned char c = data[i];
putchar(' ');
for (unsigned char m = 1 << 7; m != 0; m >>= 1)
putchar((c & m) ? '1' : '0');
}
for (; i < BYTES_BIN; ++i)
printf(" ");
}

static void print_chars(const char* data, long count) {
for (long i = 0; i < count; ++i) {
unsigned char c = data[i];
putchar(isprint(c) ? c : '.');
}
}

static bool string_to_long(const char* str, long* value) {
char* eptr;
long result = strtol(str, &eptr, 0);
if (errno || *eptr || result < 0)
return false;
*value = result;
return true;
}

static void usage(const char* program) {
fprintf(stderr, "usage: %s [-b] [-s skip] [-n length] filename\n", program);
}

int main(int argc, char** argv) {
long offset = 0;
long max_length = LONG_MAX;
bool binary = false;
int i = 1;
for (; i < argc && argv[i][0] == '-'; ++i) {
switch (argv[i][1]) {
case 's':
if (++i == argc) {
usage(argv[0]);
return EXIT_FAILURE;
}
if (!string_to_long(argv[i], &offset)) {
fprintf(stderr, "Invalid skip '%s'.\n", argv[i]);
return EXIT_FAILURE;
}
break;
case 'n':
if (++i == argc) {
usage(argv[0]);
return EXIT_FAILURE;
}
if (!string_to_long(argv[i], &max_length)) {
fprintf(stderr, "Invalid length '%s'.\n", argv[i]);
return EXIT_FAILURE;
}
break;
case 'b':
binary = true;
break;
default:
usage(argv[0]);
return EXIT_FAILURE;
}
}
if (i + 1 != argc) {
usage(argv[0]);
return EXIT_FAILURE;
}
FILE* fp = fopen(argv[i], "rb");
if (!fp) {
perror(argv[i]);
return EXIT_FAILURE;
}
if (fseek(fp, 0, SEEK_END)) {
perror("fseek");
fclose(fp);
return EXIT_FAILURE;
}
long max_offset = ftell(fp);
if (offset > max_offset)
offset = max_offset;
if (fseek(fp, offset, SEEK_SET)) {
perror("fseek");
fclose(fp);
return EXIT_FAILURE;
}
char data[BYTES_HEX];
const long max_count = binary ? BYTES_BIN : BYTES_HEX;
for (long length = 0; length <= max_length;) {
printf("%08lx", offset);
long count = fread(data, 1, max_count, fp);
if (count > max_length - length)
count = max_length - length;
if (count == 0) {
putchar('\n');
break;
}
if (binary)
print_binary(data, count);
else
print_hex(data, count);
printf(" |");
print_chars(data, count);
printf("|\n");
offset += count;
length += count;
}
fclose(fp);
return EXIT_SUCCESS;
}</syntaxhighlight>

{{out}}
Hexadecimal output:
<pre>
00000000 ff fe 52 00 6f 00 73 00 65 00 74 00 74 00 61 00 |..R.o.s.e.t.t.a.|
00000010 20 00 43 00 6f 00 64 00 65 00 20 00 69 00 73 00 | .C.o.d.e. .i.s.|
00000020 20 00 61 00 20 00 70 00 72 00 6f 00 67 00 72 00 | .a. .p.r.o.g.r.|
00000030 61 00 6d 00 6d 00 69 00 6e 00 67 00 20 00 63 00 |a.m.m.i.n.g. .c.|
00000040 68 00 72 00 65 00 73 00 74 00 6f 00 6d 00 61 00 |h.r.e.s.t.o.m.a.|
00000050 74 00 68 00 79 00 20 00 73 00 69 00 74 00 65 00 |t.h.y. .s.i.t.e.|
00000060 20 00 3d d8 00 de 2e 00 | .=.....|
00000068
</pre>
Binary output:
<pre>
00000000 11111111 11111110 01010010 00000000 01101111 00000000 |..R.o.|
00000006 01110011 00000000 01100101 00000000 01110100 00000000 |s.e.t.|
0000000c 01110100 00000000 01100001 00000000 00100000 00000000 |t.a. .|
00000012 01000011 00000000 01101111 00000000 01100100 00000000 |C.o.d.|
00000018 01100101 00000000 00100000 00000000 01101001 00000000 |e. .i.|
0000001e 01110011 00000000 00100000 00000000 01100001 00000000 |s. .a.|
00000024 00100000 00000000 01110000 00000000 01110010 00000000 | .p.r.|
0000002a 01101111 00000000 01100111 00000000 01110010 00000000 |o.g.r.|
00000030 01100001 00000000 01101101 00000000 01101101 00000000 |a.m.m.|
00000036 01101001 00000000 01101110 00000000 01100111 00000000 |i.n.g.|
0000003c 00100000 00000000 01100011 00000000 01101000 00000000 | .c.h.|
00000042 01110010 00000000 01100101 00000000 01110011 00000000 |r.e.s.|
00000048 01110100 00000000 01101111 00000000 01101101 00000000 |t.o.m.|
0000004e 01100001 00000000 01110100 00000000 01101000 00000000 |a.t.h.|
00000054 01111001 00000000 00100000 00000000 01110011 00000000 |y. .s.|
0000005a 01101001 00000000 01110100 00000000 01100101 00000000 |i.t.e.|
00000060 00100000 00000000 00111101 11011000 00000000 11011110 | .=...|
00000066 00101110 00000000 |..|
00000068
</pre>


=={{header|FreeBASIC}}==
=={{header|FreeBASIC}}==