Write a program that prompts the user for an input file name, opens the file as
ID: 3767263 • Letter: W
Question
Write a program that prompts the user for an input file name, opens the file as binary read-mode, and displays the first 256 bytes of the input file on the screen, as hex and their ASCII equivalent. Display 16 bytes per line, separated by a space, and then the ASCII for the same 16 bytes, to the right, no spaces. Try your program on a text file and a binary Bitmap file (and maybe an XLS file also). Example session screen shot below. Hint: to display a byte as hex, use printf("%3hhX", (unsigned char)mybyte); and to display a byte as a char, use printf("%c", (unsigned char)mybyte
Explanation / Answer
* fhdump.prg
parameters filename, start, stop, dwidth
private talking, hex_ascii, d_len, di, str16, d_str, hex_str
if set("talk") = "ON"
set talk OFF
talking = .T.
else
talking = .F.
endif
crlf = chr(13) + chr(10) && for convenience
hex_ascii = "" && buffer for output line
dwidth = min(dwidth, 200) && largest reasonable display width
dwidth = max(dwidth, 1) && smallest reasonable display width
fh = fopen(filename) && open file at low level
if fh > 0 && proceed only if valid handle
? && begin new line
xi = fseek(fh, start) && skip to desired offset in file
do while !feof(fh) AND xi <= stop && stop at end of file
raw = fread(fh, dwidth) && read a block of desired size
hex_str = padr(hex(raw, " "), dwidth * 3) && pad short line
hex_ascii = str(xi, 5) +": "+ hex_str +"| "+ strip(raw) + crlf
?? hex_ascii && offset: hex digits | stripped ASCII
xi = xi + dwidth && bump the offset
enddo
endif
fh = fclose(fh) && housekeeping
if talking
set talk ON
endif
return
* most output devices don't deal well with control characters, so ...
function strip && replace control chars in string with '.'
parameters rawstring
private outstring, sx, byte
outstring = ""
for sx = 1 to len(rawstring) && examine each byte in string
byte = substr(rawstring, sx, 1) && get single byte
outstring = outstring + iif(asc(byte) > 31, byte, ".")
endfor && keep printables, convert controls
return outstring
* convert a string of bytes to hex, padded with 'padchar'
function hex
parameters string, padchr && bytes and separator
private nbytes, hex_str, ix, bc
padchr = iif(type("padchr") = "C", padchr, "") && optional separator
hex_str = "" && result buffer
nbytes = len(string) && count the bytes
for ix = 1 to nbytes && and one by one ...
bc = substr(string, ix, 1) && extract a byte
hex_str = hex_str + hdigits(bc) + iif(ix = nbytes, "", padchr)
endfor && and build result hex digit string
return hex_str
* render a byte as a pair of hex digits
function hdigits
parameters char
private ch_hi, ch_lo, av, nib
av = asc(char) && ASCII value of byte
nib = int(av / 16) && high order nibble
ch_hi = chr(nib + iif(nib > 9, 55, 48)) && hex nibble
nib = mod(av, 16) && low order nibble
ch_lo = chr(nib + iif(nib > 9, 55, 48)) && hex nibble
return ch_hi + ch_lo && two nibbles to a byte
eof
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.