Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Re: Format question

by roboticus (Chancellor)
on Dec 03, 2019 at 21:11 UTC ( #11109625=note: print w/replies, xml ) Need Help??


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.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://11109625]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (7)
As of 2020-06-04 18:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Do you really want to know if there is extraterrestrial life?



    Results (35 votes). Check out past polls.

    Notices?