perlnewby:
In your format specifier, you have '%24f' for the third column in the first line, but '%14f' for the matching column in the second line which is why the string 'mils' is pushed so far to the right. It's saying "the third column is a float and should fill 24 columns", so by changing it to '%14f' to match the second line, you should get the fourth column on both lines to align.
What I frequently do in cases like this is to first break a multiline format at the line break:
my $fmt = "%-13s % 24f %-24f %-4s\n"
. " %38.6f %-14f %-4s\n";
And then add some 'fake' fields so that I can use the same formatting on both lines, and in the print statement, just insert '' for the arguments matching the fake fields:
my $fmt = "%-13s % 24f %-14f %-4s\n"
. "%-13s %24.6f %-14f %-4s\n";
. . . .
printf $fmt, 'MM_STD_gate', 152.401574, -22.047244, 'mils',
'', 3871.0, -560.0, 'microns';
When you're doing things that aren't time critical, I find it useful to do something like this to make adjusting the format easier and paying a slight loss of inefficiency.
Note: The formats for the printf() family of functions are pretty convenient, but have some limitations when you're trying to make text reports. Specifically, controlling field widths, aligning values on decimal points, etc., can be difficult. In fact, your format with the %-4s at the end is blowing past your formatted column width for the 'microns' field. Not important, as it's the last field on the line, but if you added another column to the right, you'd discover it fairly soon!
A lesser-used output formatting technique when you're trying to reports on monospaced devices (like the console or a line printer) is the 'named formats' method of formatting text. (You can read the details about it with the 'perldoc perlform' command.) It's not something you necessarily want to use often, but you should read about it once or twice so you can be aware of it in the event that you want to use it in the future. It's kind of a throwback to the way reports are frequently done in COBOL on mainframes. One advantage of it is that it can handle top of form and bottom of form for printouts, and it's visually easy to edit. It also doesn't blow out the column widths: instead of breaking the report format, it fills fields that are too wide with '#####' instead (for numbers) or it just truncates the value (for text).
However, now that we're in a more modern era where monospaced output isn't nearly so common and online reports are easier to deal with (and more environmentally friendly that printing a ream of paper for a report you'll use twice and then discard), it would be better to read about Template::Toolkit where you can generate *many* types of reports, flexibly.
I was still waking up with my morning coffee, so I took a few minutes and put together a quickie demo of the first two techniques below. (I didn't demo the third technique because I don't have Template::Toolkit installed on this machine (and don't really use it much anyway.)
Roboticus@Waubli ~
$ cat t.pl
use strict;
use warnings;
# The data
my @recs = (
[ 'MM_MM_STD_gate', 152.401574, -22.047244, 'mils',
3871.0, -560.0, 'microns' ],
[ 'RFN_a', 337.244094, 0.787402, 'mils',
8566.0, 20.0, 'microns' ],
[ 'RFN_b', 366.181102, 0.787402, 'mils',
9301.0, 20.0, 'microns' ],
[ 'RFN_c', 376.929133, 0.787402, 'mils',
9574.0, 20.0, 'microns' ],
[ 'MM_STD2_gate', -259.488188, -22.047244, 'mils',
-6591.0, -560.0, 'microns' ],
[ 'RBASE_right_2', -366.181102, -33.464566, 'mils',
-9301.0, -850.0, 'microns' ],
);
print "\n------ Report1: (printf) ------\n\n";
# I made it easy on myself by *not* using the fake field here so I cou
+ld
# just print the data by expanding the data in-line in the printf stat
+ement.
my $fmt = "%-13s % 24f %-14f %-4s\n"
. " %24.6f %-14f %-4s\n";
for my $ar (@recs) {
printf $fmt, @$ar;
}
print "\n\n------ Report 2 (Named formats) ------\n\n";
# The format statement embeds the variables to map to the fields inlin
+e, so
# the variable must already be declared
my $ar;
# Define the format visually, along with the variables to stuff into t
+hem
format DETAIL =
@<<<<<<<<<<<< @####.##### @###.###### @<<<<<<<<<
$ar->[0], $ar->[1], $ar->[2], $ar->[3],
@####.##### @###.###### @<<<<<<<<<
$ar->[4], $ar->[5], $ar->[6];
.
# Specify the format type to use for each write statement (you can hav
+e
# multiple formats and switch between them as needed).
select(STDOUT);
$~ = "DETAIL";
# Print the report
for $ar (@recs) {
write;
}
Roboticus@Waubli ~
$ perl t.pl
------ Report1: (printf) ------
MM_MM_STD_gate 152.401574 -22.047244 mils
3871.000000 -560.000000 microns
RFN_a 337.244094 0.787402 mils
8566.000000 20.000000 microns
RFN_b 366.181102 0.787402 mils
9301.000000 20.000000 microns
RFN_c 376.929133 0.787402 mils
9574.000000 20.000000 microns
MM_STD2_gate -259.488188 -22.047244 mils
-6591.000000 -560.000000 microns
RBASE_right_2 -366.181102 -33.464566 mils
-9301.000000 -850.000000 microns
------ Report 2 (Named formats) ------
MM_MM_STD_gat 152.40157 -22.047244 mils
3871.00000 -560.000000 microns
RFN_a 337.24409 0.787402 mils
8566.00000 20.000000 microns
RFN_b 366.18110 0.787402 mils
9301.00000 20.000000 microns
RFN_c 376.92913 0.787402 mils
9574.00000 20.000000 microns
MM_STD2_gate -259.48819 -22.047244 mils
-6591.00000 -560.000000 microns
RBASE_right_2 -366.18110 -33.464566 mils
-9301.00000 -850.000000 microns
...roboticus
When your only tool is a hammer, all problems look like your thumb. |