I got this exercise and I think I've got it done. Can anyone show me how to make it better? It's a program that takes a file and makes a hex dump. The program has to print 10 bytes and the characters that correspond to the bytes. Whitespace is turned into periods. If the file has "a test file", the output should be
This is the code I have now.Code:61 20 74 65 73 74 20 66 69 6C a.test.fil
65 00 00 00 00 00 00 00 00 00 e
Do any gurus here think it's OK or do I need to try something else?Code:#include <ctype.h>
#include <stdio.h>
#include <string.h>
#define NBYTES 10 // # of bytes per row
void hex_dump(FILE *fp);
int load_bytes(FILE *fp, char row[], int size);
void print_hex(char row[], int n, int limit);
void print_row(char row[], int n);
int printable_char(int ch);
int main(void)
{
fputs("Select a file: ", stdout);
char filename[BUFSIZ];
if ( fgets(filename, BUFSIZ, stdin) != NULL )
{
// Trim '\n' from the filename
size_t len = strlen(filename);
if ( filename[len - 1] == '\n' )
{
filename[len - 1] = '\0';
}
// Run the hex dump
FILE *fp = fopen(filename, "r");
if ( fp != NULL )
{
hex_dump(fp);
fclose(fp);
}
}
}
// Print the contents of a file as hex
void hex_dump(FILE *fp)
{
int n;
do
{
char row[NBYTES + 1]; // +1 for '\0'
n = load_bytes(fp, row, NBYTES);
if ( n > 0 )
{
print_hex(row, n, NBYTES);
print_row(row, n);
putchar('\n');
}
}
while ( n > 0 );
}
// Read up to size bytes into a string
// Return the number of bytes read
int load_bytes(FILE *fp, char row[], int size)
{
int n = 0;
int ch;
while ( n < size && (ch = fgetc(fp)) != EOF )
{
row[n++] = ch;
}
row[n] = '\0';
return n;
}
// Print the hex version of the characters in a string
void print_hex(char row[], int n, int limit)
{
// Always print limit values
// Use 0 for values past n
for ( int i = 0; i < limit; ++i )
{
int value = row[i];
if ( i >= n )
{
value = 0;
}
printf("%02X ", value);
}
}
// Print a display version of the string
void print_row(char row[], int n)
{
for ( int i = 0; i < n; ++i )
{
putchar(printable_char(row[i]));
}
}
// Make a character printable
// even if it's whitespace
int printable_char(int ch)
{
if ( isspace(ch) )
{
return '.';
}
else
{
return ch;
}
}