in reply to Write 2 uint16_t numbers to file in Perl

You are unpacking a binary representation of a bunch of unsigned shorts ($hdr) into an array of perl scalars (@rgb), then replacing two elements in that array with packed unsigned shorts, which isn't what you want. Just substitute the new values directly into the array:

$rgb[16] = 7360; # Overwrite 3689 with 7360 $rgb[22] = 4912; # 2462 -> 4912

Now if you want to write this scalar array back to a binary file, try:

open(my $outfile, '>:raw', $hfn) or die "Couldn't open $hfn: $!\n"; # Overwrites existing file print $outfile pack("S*", @rgb); close($outfile) or die "Couldn't close $hfn: $!\n";

(The :raw modifier on the second argument of open is equivalent to using binmode).

If you know beforehand the positions and values in the binary file you need to change, you can save yourself the trouble of reading it all in to memory, unpacking everything to an array and re-packing it all at the end by just editing it in place:

open(my $fh, '+<:raw', $hfn) or die "Couldn't open $hfn: $!\n"; seek($fh, 2*16, 0); # Double up 'cause 'seek' wants bytes not short +ints print $fh pack('S', 7360); seek($fh, 2*22, 0); print $fh pack('S', 4912); close($fh) or die "Couldn't close $hfn: $!\n";

Replies are listed 'Best First'.
Re^2: Write 2 uint16_t numbers to file in Perl
by AnomalousMonk (Archbishop) on Jan 05, 2016 at 18:54 UTC
    seek($fh, 2*16, 0); # Double up 'cause 'seek' wants bytes not short ints

    Rather than having numeric literals running around all over the place, it's possible to capture pack-spec widths:

    c:\@Work\Perl>perl -wMstrict -le "use constant SIZEOF_S => length pack 'x[S]'; print SIZEOF_S; ;; use constant SIZEOF_WHATEVER => length pack 'x[NSc]'; print SIZEOF_WHATEVER; " 2 7
    (It may be perfectly safe to use the shorter  'S' etc., rather than the more verbose  'x[S]' form in the pack statement, but I have the sneaking suspicion that a pitfall may lurk there... can't remember it atm.)


    Give a man a fish:  <%-{-{-{-<

      The OP needs to match his pack/unpack template to the data, not the other way around. If anything, he might want to consider 'n' vs 'v' vs 'S'.