Home > Net >  Perl printf line breaks
Perl printf line breaks

Time:09-17

Looking to add a line break after every 16 bytes of the 100 bytes printed from j. All 100 bytes are currently printed on one line at the moment.

Any assistance would be great full, thanks.

for ($j = 6; $j < 106; $j  )
        {
            printf("X ", hex(@bytes[$j]));
        }
        printf("\t");

Thanks all. I approached it another way. In the end the visual aspect was not a concern as I ended up printing to file anyway. This data then gets pasted in a hex editor so formatting was a forethought rather than a need be. The below is now outputting all the data I was looking for in the end rather than a predetermined length.

for ($j = 6; $j < @bytes; $j = $j   1)      
        {
            printf outfile ("X ", hex(@bytes[$j]));
        }
        printf("\n");

CodePudding user response:

Use splice() to grab 16 elements at a time from your array.

I've also switched to using say(), join(), map() and sprintf().

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';

my @bytes = map { int(rand(255)) } 0..200;

# As splice is destructive, take a copy of the array.
# Also, let's remove those first six elements and any
# after index 106.

my @data = @bytes[6 .. 105];

while (my @row = splice @data, 0, 16) {
  say join ' ', map { sprintf 'X', $_ } @row;
}

Update: A few more Perl tips for you.

  • Always add use strict and use warnings to the top of your Perl programs. And fix the problems they will show you.
  • @bytes[$j] is better written as $bytes[$j] (as it's a single value). That's one of the things use warnings will tell you about.
  • for ($j = 6; $j < 106; $j ) is probably better written as for my $j (6 .. 105). Less chance of "off-by-one" errors.
  • Actually, as you're just using $j to get the element from the array, you probably want to just iterate across the elements of the array directly - for my $elem (@bytes[6 .. 105]) (and then using $elem in place of $bytes[$j]).

CodePudding user response:

You can utilize some $counter and print \n once $counter % 16 equal 0.

use strict;
use warnings;

my @bytes = map { int(rand(255)) } 0..200;
my $counter = 1;

for ( @bytes[6..106] ) {
    printf "X ", $_;
    print "\n" unless $counter   % 16;
}

print "\n";

Output sample

C9 CA E7 66 13 F5 56 BE 08 68 E4 22 93 77 E0 14
08 4F F3 AD CC F4 66 DE 6C BB 1B E6 CE F3 13 DD
AE 6A CD 9B 5E 98 1F D4 2E C5 80 4B 3E 8E BC BF
5B 27 F9 0D 97 AB 26 C0 11 2D 1D 95 CE 26 3C D8
3C D8 A4 06 0A 48 0D 45 53 28 7E 5D D2 AD 90 5C
03 32 95 48 F6 DB 20 90 A7 62 41 3D D7 AB 7C 3B
CF 3D 0D C2 DA 

Note: index from 6 to 106 gives 101 element

CodePudding user response:

Short and fast:

sub hex_dump {
   my $i = 0;
   my $d = uc unpack 'H*', pack 'C*', @_;
   $d =~ s{ ..\K(?!\z) }{   $i % 16 ? " " : "\n" }xseg;
   return "$d\n";
}

print hex_dump(@bytes[6..105]);

There's also the very clean splice loop approach.

sub hex_dump {
   my $d = '';
   $d .= join(" ", map sprintf("X", $_), splice(@_, 0, 16)) . "\n" while @_;
   return $d;
}

print hex_dump(@bytes[6..105]);

Because this approach produces a line at a time, it's great for recreating the traditional hex dump format (with offset and printable characters shown).

$ hexdump -C a.pl
00000000  75 73 65 20 73 74 72 69  63 74 3b 0a 75 73 65 20  |use strict;.use |
00000010  77 61 72 6e 69 6e 67 73  3b 0a 0a 73 75 62 20 68  |warnings;..sub h|
00000020  65 78 5f 64 75 6d 70 20  7b 0a 20 20 20 6d 79 20  |ex_dump {.   my |
...
000000a0  74 65 73 20 3d 20 30 2e  2e 32 35 35 3b 0a 0a 70  |tes = 0..255;..p|
000000b0  72 69 6e 74 20 68 65 78  5f 64 75 6d 70 28 40 62  |rint hex_dump(@b|
000000c0  79 74 65 73 5b 36 2e 2e  31 30 35 5d 29 3b 0a     |ytes[6..105]);.|
000000cf

You could also use a for loop. You would iterate over the indexes, and print either a space or a line feed depending on the index of the byte you're printing.

sub hex_dump {
   my $d = '';
   for my $i (0..$#_) {
      $d .= sprintf("X%s", $_[$i], $i == $#_ || $i % 16 == 15 ? "\n" : " ");
   }

   return $d;
}

print hex_dump(@bytes[6..105]);
  •  Tags:  
  • perl
  • Related