http://qs321.pair.com?node_id=11109625


in reply to Format question

catfish1116:

At first, I guessed that formatting problem is that the data lines contain whitespace which caused that first field to blow up. I was going to suggest that you tell split to ignore whitespace like the following:

use strict; use warnings; my $line = <DATA>; while (defined($line = <DATA>)) { chomp($line); my @items = (split /\s*:\s*/, $line); print "Customer Name: $items[0] \t Number of Books checked out: +$items[5]\n"; } __DATA__ customer:field1:field2:field3:field4:num_checked_out wilma flintstone :1:m:n:o:3 barney rubble:1:e:i:o:5 Sam Slate :1:3:2:1:0 Great Gazoo:1:1:2:3:2 Charlie Harper:1:a:b:c:4 Neil Gruesome:1:x:y:z:6

But when I ran the script, I got the same result you did:

$ perl ex_split_ign_whitespace.pl Customer Name: wilma flintstone Number of Books checked out: + 3 Customer Name: barney rubble Number of Books checked out: 5 Customer Name: Sam Slate Number of Books checked out: 0 Customer Name: Great Gazoo Number of Books checked out: 2 Customer Name: Charlie Harper Number of Books checked out: 4 Customer Name: Neil Gruesome Number of Books checked out: 6

That's when I looked at your print statement: You're using a tab to try to align the columns. But a tab simply tells the print statement to go to the next column that's a multiple of 8. When your input data has width differences, you'll find that a field that's a shade too long pushes everything over eight more characters.

So the solution is to use printf with a width specifier (as tobyink mentioned), or the format statement (as hippo suggested) or pack or some such. I just tweaked it to use printf since it was the simplest change:

use strict; use warnings; my $line = <DATA>; while (defined($line = <DATA>)) { chomp($line); my @items = (split /\s*:\s*/, $line); printf "Customer Name: %-16s Number of Books checked out:%3u\n" +, $items[0], $items[5]; } __DATA__ customer:field1:field2:field3:field4:num_checked_out wilma flintstone :1:m:n:o:3 barney rubble:1:e:i:o:5 Sam Slate :1:3:2:1:0 Great Gazoo:1:1:2:3:2 Charlie "the Angel" Harper:1:a:b:c:4 Neil Gruesome:1:x:y:z:1026

In this version, I added a width specifier to both the customer name *and* the number of books checked out. Notice that the columns line up correctly *unless* one of the data items is too long to fit in the field (the last two lines).

$ perl ex_split_ign_whitespace.pl Customer Name: wilma flintstone Number of Books checked out: 3 Customer Name: barney rubble Number of Books checked out: 5 Customer Name: Sam Slate Number of Books checked out: 0 Customer Name: Great Gazoo Number of Books checked out: 2 Customer Name: Charlie "the Angel" Harper Number of Books checked o +ut: 4 Customer Name: Neil Gruesome Number of Books checked out:1026
One way you can handle that is to tell split that you don't care about whitespace around your delimiter, like this:

that the data has a bunch of whitespace in it, causing yo

...roboticus

When your only tool is a hammer, all problems look like your thumb.