Reading a String from a Binary File
Problem
You want to read a NUL-terminated string from a file, starting at a particular address.
Solution
Set $/
to an ASCII NUL, and read the string with
<>:
$old_rs = $/; # save old $/ $/ = "\0"; # NULL seek(FH, $addr, SEEK_SET) or die "Seek error: $!\n"; $string = <FH>; # read string chomp $string; # remove NULL $/ = $old_rs; # restore old $/
You can use local
to save and restore
$/
if you want:
{ local $/ = "\0"; # ... } # $/ is automatically restored
Discussion
The example program shown in Example 8.5, bgets , accepts a filename and one or more byte addresses as arguments. Decimal, octal, or hexadecimal addresses may be specified. For each address, the program reads and prints the NULL- or EOF-terminated string at that position:
Example 8-5. bgets
#!/usr/bin/perl # bgets - get a string from an address in a binary file use IO::Seekable; ($file, @addrs) = @ARGV or die "usage: $0 file addr ..."; open(FH, $file) or die "cannot open $file: $!"; $/ = "\000"; foreach $addr (@addrs) { $addr = oct $addr if $addr =~ /^0/; seek(FH, $addr, SEEK_SET) or die "can't seek to $addr in $file: $!"; printf qq{%#x %#o %d "%s"\n}, $addr, $addr, $addr, scalar <>; }
Here’s a simple implementation of the Unix strings program:
Example 8-6. strings
#!/usr/bin/perl # strings - pull strings out of a binary file $/ = "\0"; while (<>) { while (/([\040-\176\s]{4,})/g) { print $1, "\n"; } }
See Also
The seek
, getc
, and
ord
functions in perlfunc
(1)
and in Chapter 3 of Programming ...
Get Perl Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.