Hex Dump

Dave Sinkula 0 Tallied Votes 241 Views Share

This is a quick and dirty example of a hex dump utility. Not much in the way of special features -- it just dumps the contents of a hard-coded filename in hex and also shows the characters. An example that can show the basics of making your own.

#include <stdio.h>
#include <ctype.h>

/**
 * Display the contents of a stream as hexadecimal bytes and text.
 * @param  file  pointer to a binary stream
 * @return the number of bytes in the file read
 */
size_t hexdump(FILE *file)
{
   unsigned char data[16];
   size_t i, j, size, count = 0;
   /*
    * Heading
    */
   fputs("         ", stdout); /* skip address area */
   for ( i = 0; i < sizeof data / sizeof *data; ++i )
   {
      printf("+%lX ", (long unsigned)i);
   }
   puts("Text");
   /*
    * Body
    */
   do {
      /* Read some data. */
      size = fread(data, sizeof *data, sizeof data / sizeof *data, file);
      if ( size )
      {
         /* Print the base address. */
         printf("%08lX ", (long unsigned)count);
         count += size; /* adjust the base address */
         /* Print the characters' hex values. */
         for ( i = 0; i < size; ++i )
         {
            printf("%02X ", data[i]);
         }
         /* Pad the hex values area if necessary. */
         for ( ++i; i <= sizeof data / sizeof *data; ++i )
         {
            fputs("   ", stdout);
         }
         /* Print the characters (use '.' for non-printing characters). */
         for ( j = 0; j < size; j++ )
         {
            putchar(isprint(data[j]) ? data[j] : '.');
         }
         putchar('\n');
      }
   } while ( size == sizeof data / sizeof *data ); /* Break on partial count. */
   return count;
}

int main(void)
{
   static const char filename[] = __FILE__; /* may not work on everywhere */
   FILE *file = fopen(filename, "rb");
   if ( file != NULL )
   {
      printf("%lu bytes\n", (long unsigned)hexdump(file));
      fclose(file);
   }
   else
   {
      perror(filename);
   }
   return 0;
}

Dani AI

Generated

Nice, compact example from that shows the essential hex-dump workflow: read fixed-size blocks, print an offset, print each byte in hex, and show printable characters alongside. The implementation is a good learning reference; the remarks below highlight correctness, portability, and small improvements that make the routine more robust for real-world use.

Portability and correctness notes: offsets and totals are stored in size_t but printed with a cast to long unsigned and %lX; that can truncate on platforms where size_t is wider than unsigned long (common on some 64-bit ABIs). Prefer the z length modifier for size_t (for example printf("%08zx", offset)) or convert to uintmax_t and use the PRIxMAX macros from <inttypes.h> when fixed-width safety is needed. When calling isprint, ensure an unsigned char (or an explicit cast) is passed to avoid undefined behavior if a plain char is signed. Likewise, cast bytes to an unsigned integer when feeding %02X to printf to avoid subtle varargs-promotion issues.

Feature and performance ideas: keep the 16-byte output layout but read larger buffers (4K or 64K) and emit 16-byte lines from that buffer to reduce syscall overhead. For very large files, use 64-bit-aware functions (fseeko/ftello or off_t/stat) so offsets are not truncated. Optional niceties include a visible separator between hex and ASCII, grouping bytes (2/4 bytes), suppressing repeated identical lines (like many hexdumps do), or supporting C-array output for embedding binary blobs.

Error handling and usage: accept filenames via argv and fall back to stdin when none is given; treat non-seekable inputs (pipes) specially because ftell/fseek won't work. Test with files containing non-ASCII bytes and very large files to validate alignment, padding, and offset-width behavior before deploying the utility.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.