Last active
October 4, 2025 19:38
-
-
Save michelesr/4de54ab2d44ac068b088a4a4bc4190de to your computer and use it in GitHub Desktop.
Simple xxd like implementation of hexdump in ANSI C
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include <ctype.h> | |
| #include <string.h> | |
| #include <stdint.h> | |
| #include <errno.h> | |
| int main(int argc, char *argv[]) { | |
| FILE *file = stdin; /* file to read, default to stdin */ | |
| char text[17]; /* text representation of the 16 bytes line */ | |
| int n; /* number of bytes read in the line */ | |
| int i; /* position in the current 16 bytes line */ | |
| uint8_t bytes[16]; /* buffer containing the read bytes line */ | |
| uint8_t padding; /* padding spaces to align the text representation in the last line */ | |
| uint64_t offset = 0; /* total bytes read */ | |
| if (argc > 1) { | |
| file = fopen(argv[1], "rb"); | |
| if (file == NULL) { | |
| fprintf(stderr, "Error opening file %s: %s\n", argv[1], strerror(errno)); | |
| return 1; | |
| } | |
| } | |
| while ((n = fread(bytes, sizeof(*bytes), 16, file)) > 0) { | |
| /* print the offset eg "00000010: " */ | |
| printf("%08llx: ", offset); | |
| /* for each byte in the line */ | |
| for (i = 0; i < n; i++) { | |
| unsigned char b = bytes[i]; | |
| /* print the byte hex value */ | |
| printf("%02x", b); | |
| /* print a space every 2 bytes */ | |
| if (i % 2 == 1) putchar(' '); | |
| /* set the text representation of the byte */ | |
| text[i] = isprint(b) ? b : '.'; | |
| } | |
| text[i] = '\0'; | |
| /* if it's the last line and shorter than 16 bytes */ | |
| if (i < 16) { | |
| /* calculate the missing bytes */ | |
| i = 16 - i; | |
| /* calculate the number of spaces, 2 for each byte, and 1 for each byte pair */ | |
| padding = (i * 2 + (i / 2)); | |
| /* if the number of missing bytes is odd, we need another space */ | |
| if (i % 2 == 1) padding++; | |
| for (i = 0; i < padding; i++) putchar(' '); | |
| } | |
| /* print the text representation of the line */ | |
| printf(" %s\n", text); | |
| offset += n; | |
| } | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment