Skip to content

Corg-Labs/hexview

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 

Repository files navigation

Hex View

Hexdump clone: hex + ASCII view of any file, in C.

A small, self-contained demo written in pure C — no external libraries, just the standard library and POSIX. Part of the Corg-Labs collection of single-file C programs.


How It Works

  1. Input is read 16 bytes at a time
  2. Each row prints the byte offset, then 16 hex values
  3. A gap splits the row into two 8-byte halves for readability
  4. Printable bytes are shown in an ASCII gutter, others as '.'

Tutorial

This tutorial walks through every stage of hexview.c, from opening the file to printing the final ASCII gutter, explaining the data layout and rendering choices along the way.

1. Opening the Input Source

The program accepts either a filename argument or piped stdin. A single conditional selects the right FILE * before any reading begins:

FILE *f = (argc > 1) ? fopen(argv[1], "rb") : stdin;
if (!f) { perror("open"); return 1; }

Opening in "rb" (read-binary) mode is important: on Windows it prevents newline translation, and on all platforms it signals that every byte — including nulls — should be delivered unmodified.

2. The 16-Byte Read Buffer

The entire rendering model is built around one small buffer:

unsigned char buf[16];
long off = 0;
size_t r;

buf holds one row's worth of data. off tracks the running byte offset (printed as the address at the start of each row). r is the number of bytes actually read by the current fread call — it will be less than 16 for the final row of most files.

3. The Main Read Loop

All work happens inside a single while loop that terminates when fread returns zero (EOF or error):

while ((r = fread(buf, 1, 16, f)) > 0) {
    /* print offset, hex columns, ASCII gutter */
    off += r;
}

Each iteration processes exactly one output row. off is incremented by r (not by the fixed value 16) so that the address shown on the last row is always accurate, even when the file length is not a multiple of 16.

4. Printing the Byte Offset

The first field on every row is the file offset of buf[0], zero-padded to eight hex digits:

printf("%08lx  ", off);

This matches the classic xxd/hexdump layout: the address is always exactly 10 characters wide (8 digits + 2 spaces), so columns stay aligned regardless of file size (up to 4 GiB with a 32-bit long; larger on 64-bit platforms).

5. Rendering the Hex Columns (with the Mid-Row Gap)

The hex section loops over all 16 column positions, printing either a two-digit hex value or three spaces for positions past the end of the buffer:

for (size_t i = 0; i < 16; i++) {
    if (i < r) printf("%02x ", buf[i]); else printf("   ");
    if (i == 7) putchar(' ');
}

The if (i == 7) putchar(' ') inserts an extra blank after the eighth column. This splits the 16 hex values into two visual groups of 8, making it easier to locate a byte by eye when scanning long output.

6. The ASCII Gutter

After the hex columns, a |…|-delimited gutter shows the printable representation of every byte in the row:

printf(" |");
for (size_t i = 0; i < r; i++)
    putchar((buf[i] >= 32 && buf[i] < 127) ? buf[i] : '.');
printf("|\n");

The range [32, 127) is the printable subset of ASCII: space through ~. Bytes outside that range — control characters, high bytes from UTF-8 sequences, binary data — are replaced with . so the gutter never emits unprintable characters that would corrupt a terminal.

7. Clean-Up and Exit

After the loop, the file is closed only when it was opened from a path argument (closing stdin is unnecessary and potentially harmful):

if (argc > 1) fclose(f);
return 0;

Returning 0 signals success; the earlier return 1 after a failed fopen is the only non-zero exit path, keeping the error-handling contract simple and scriptable.


Build

gcc hexview.c -o hexview

Run

./hexview file        # or:  cat file | ./hexview

Controls

Pass a file as an argument, or pipe data on stdin.

About

► Hexdump clone: hex + ASCII view of any file, in C.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages