3 * gcc hexdump.c -o hexdump -Wall -W -Wextra -ansi -pedantic
8 #include <string.h> /* for memset() */
9 #include <getopt.h> /* FIXME: make it portable */
11 /* Function prototypes */
12 void diep(const char *s
);
13 void dieu(const char *pname
);
15 #define BUFSIZE 20 /* Must be dividable by 2 */
17 int main(int argc
, char *argv
[])
19 unsigned char buf
[BUFSIZE
+ 1]; /* +1 for the '\0' */
21 int caps
, cnt
, i
, j
, len
, opt
, skip
;
22 int readbytes
, totalbytes
;
30 while ((opt
= getopt(argc
, argv
, "Cn:s:f:")) != -1) {
49 /* optind shows to the argv[] index of the first non-option element */
51 fprintf(stderr
, "non-option argv[]-elements: ");
53 fprintf(stderr
, "%s ", argv
[optind
++]);
54 fprintf(stderr
, "\n");
62 if ((fp
= fopen(fpath
, "r")) == NULL
)
65 /* Skip `skip' bytes */
66 fseek(fp
, skip
, SEEK_SET
);
71 while(!feof(fp
) && (totalbytes
< len
|| len
== -1)) {
72 /* Initialize buffer */
73 memset(buf
, 0, BUFSIZE
);
75 /* Read `BUFSIZE' elements of 1 byte long from file */
76 readbytes
= fread(buf
, 1, BUFSIZE
, fp
);
79 printf(caps
== 1 ? "%08lX " : "%08lx ", (unsigned long)cnt
* BUFSIZE
+ skip
);
81 i
< readbytes
&& (totalbytes
< len
|| len
== -1);
83 printf(caps
== 1 ? "%02X " : "%02x ", buf
[i
]);
84 if (i
== (BUFSIZE
/ 2) - 1)
88 /* Fill in the blanks */
89 for (j
= 0; j
< (BUFSIZE
- i
); j
++) {
91 if (j
== (BUFSIZE
/2) - 1)
96 * Print the output characters in the default character set.
97 * Nonprinting characters are displayed as a single `.'
100 for (j
= 0; j
< i
; j
++) {
101 if (buf
[j
] >= 32 && buf
[j
] <= 127)
102 printf("%c", buf
[j
]);
114 /* Close device file */
120 void diep(const char *s
)
126 void dieu(const char *pname
)
128 fprintf(stderr
, "Usage: %s [-C] [-n length] [-s skip] -f file\n", pname
);