📄 ch11.htm
字号:
You might be wondering how Perl decides when a word ends. This
behavior is controlled by the <TT>$:</TT>
variable. The default value for <TT>$:</TT>
is a string consisting of the space, newline, and dash characters.
<H3><A NAME="ExampleWritingtoaFileInsteadofISTDOUTI">
Example: Writing to a File Instead of <I>STDOUT</I></A></H3>
<P>
Up to this point in the chapter, we've only looked at writing
a report to the display or <TT>STDOUT</TT>.
This was done to simplify and shorten the examples. Writing a
report to a file requires that you open a file for output and
specify the file handle as a parameter to the <TT>write()</TT>
fuNCtion. All fuNCtionality you've seen so far can be used with
files.
<P>
Listing 11.9 shows how easy it is to convert an existing program
from using <TT>STDOUT</TT> to using
a file. The program shown is a reworking of the program in Listing
11.4. Four changes needed to be made for the conversion. The <TT>format</TT>
statement was changed to specify a format name identical to the
file handle used in the second <TT>open()</TT>
statement. A second <TT>open()</TT>
statement was added. The <TT>write()</TT>
fuNCtion was changed to specify the file handle to use, and a
second <TT>close()</TT> statement
was added.
<P>
<IMG SRC="pseudo.gif" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/pseudo.gif" BORDER=1 ALIGN=RIGHT><p>
<BLOCKQUOTE>
<I>Declare a format for the </I><TT><I>CD_REPORT</I></TT><I>
file handle.<BR>
Open the </I><TT><I>FORMAT.DAT</I></TT><I>
file, read all the lines into </I><TT><I>@lines</I></TT><I>,
and then close the file.<BR>
Open the </I><TT><I>FORMAT.RPT</I></TT><I>
file for output to hold the report.<BR>
Iterate over the </I><TT><I>@lines</I></TT><I>
array.<BR>
Remove the linefeed character.<BR>
Split the string into three fields.<BR>
If any of the three fields is not present in the line, provide
a default value of an empty string. Notice that a numeric value
must be given to </I><TT><I>$price</I></TT><I>
instead of the empty string.<BR>
Invoke the </I><TT><I>format</I></TT><I>
statement by using the </I><TT><I>write()</I></TT><I>
fuNCtion specifying the file handle to use.<BR>
Close the </I><TT><I>FORMAT.RPT</I></TT><I>
file.</I>
</BLOCKQUOTE>
<HR>
<BLOCKQUOTE>
<B>Listing 11.9 11LST09.PL-Using a Format with <I>STDOUT
<BR>
</I></B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<PRE>
format CD _REPORT =
Album=@<<<<<<<<<<<<< Artist=@>>>>>>>>>>>> Price=$@##.##
$album, $artist, $price
.
open(FILE, "<format.dat");
@lines = <FILE>;
close(FILE);
open(CD_REPORT, ">format.rpt");
foreach (@lines) {
chop;
($album, $artist, $price) = (split(/!/));
$album = "" if !defined($album);
$artist = "" if !defined($artist);
$price = 0 if !defined($price);
write(CD_REPORT);
}
</PRE>
</BLOCKQUOTE>
<HR>
<BLOCKQUOTE>
<PRE>
close(CD_REPORT);
</PRE>
</BLOCKQUOTE>
<P>
This program creates a file called FORMAT.RPT that contains the
following:
<BLOCKQUOTE>
<PRE>
Album=The Lion King Artist= Price=$ 0.00
Album=Tumbleweed Con Artist= Elton John Price=$123.32
Album=Photographs & Artist= Jim Croce Price=$ 4.95
Album=Heads & Tales Artist= Harry Chapin Price=$ 12.50
</PRE>
</BLOCKQUOTE>
<P>
The contents of FORMAT.RPT are identical to the display created
by the program in Listing 11.4.
<P>
Using more than one format in reports destined for files is slightly
more complicated than it was when STDOUT was used. The process
is more involved because you need to make the output file handle
the default file handle before setting the <TT>$~</TT>
or <TT>$^</TT> special variables.
Listing 11.10 shows how to use an alternative format statement.
<P>
<IMG SRC="pseudo.gif" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/pseudo.gif" BORDER=1 ALIGN=RIGHT><p>
<BLOCKQUOTE>
<I>Declare a format for the </I><TT><I>CD_REPORT</I></TT><I>
file handle.<BR>
Declare a format for the total price information using </I><TT><I>CD_REPORT_TOTAL</I></TT><I>
as the format name.<BR>
Declare a heading format for the </I><TT><I>CD_REPORT</I></TT><I>
file handle using </I><TT><I>CD_REPORT_TOP</I></TT><I>
as the format name.<BR>
Declare the </I><TT><I>dotize()</I></TT><I>
fuNCtion.<BR>
Initialize local variables called </I><TT><I>$width</I></TT><I>
and </I><TT><I>$string</I></TT><I>.
<BR>
If the width of </I><TT><I>$string</I></TT><I>
is greater than </I><TT><I>$width</I></TT><I>,
return a value that consists of </I><TT><I>$string</I></TT><I>
shortened to </I><TT><I>$width-3</I></TT><I>
with </I><TT><I>...</I></TT><I> appended
to the end; otherwise, return </I><TT><I>$string</I></TT><I>.
<BR>
Open the </I><TT><I>FORMAT.DAT</I></TT><I>
file, read all the lines into </I><TT><I>@lines</I></TT><I>,
and then close the file.<BR>
Open the </I><TT><I>FORMAT.RPT</I></TT><I>
file for output to hold the report.<BR>
Initialize the </I><TT><I>$total</I></TT><I>
variable to zero.<BR>
Iterate over the </I><TT><I>@lines</I></TT><I>
array.<BR>
Remove the linefeed character.<BR>
Split the string into three fields.<BR>
Provide a default value for any empty variables.<BR>
Invoke the </I><TT><I>format</I></TT><I>
statement by using the </I><TT><I>write()</I></TT><I>
fuNCtion specifying the </I><TT><I>CD_REPORT</I></TT><I>
file name.<BR>
Change the current format by assigning a value to the </I><TT><I>$~</I></TT><I>
special variable. This statement uses some advaNCed coNCepts and
is explained further after the listing.<BR>
Invoke the </I><TT><I>format</I></TT><I>
statement by using the </I><TT><I>write()</I></TT><I>
fuNCtion.<BR>
Close the </I><TT><I>FORMAT.RPT</I></TT><I>
file.</I>
</BLOCKQUOTE>
<HR>
<BLOCKQUOTE>
<B>Listing 11.10 11LST10.PL-Using an Alternative <I>format</I>
Statement<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<PRE>
format CD_REPORT =
@<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<< $@###.##
dotize(17, $album), dotize(16, $artist), $price
.
format CD_REPORT_TOTAL =
---------------------------------------------
$@###.##
$total
.
format CD_REPORT_TOP =
@|||||||||||||||||||||||||||||||||||| Pg @<
"CD Collection of David Medinets", $%
Album Artist Price
----------------- ---------------- --------
.
sub dotize {
my($width, $string) = @_;
if (length($string) > $width) {
return(substr($string, 0, $width - 3) . "...");
}
else {
return($string);
}
}
open(FILE, "<format.dat");
@lines = <FILE>;
close(FILE);
open(CD_REPORT, ">format.rpt");
$total = 0;
foreach (@lines) {
chop();
($album, $artist, $price) = (split(/!/));
$album = "" if !defined($album);
$artist = "" if !defined($artist);
$price = 0 if !defined($price);
write(CD_REPORT);
$total += $price;
}
</PRE>
</BLOCKQUOTE>
<HR>
<BLOCKQUOTE>
<PRE>
select((select(CD_REPORT), $~ = "CD_REPORT_TOTAL")[0]);
write(CD_REPORT);
</FONT><FONT SIZE=2 FACE="Courier">close(CD_REPORT);
</PRE>
</BLOCKQUOTE>
<P>
This program creates a file called <TT>FORMAT.RPT</TT>
that contains the following:
<BLOCKQUOTE>
<PRE>
CD Collection of David Medinets Pg 1
Album Artist Price
----------------- ---------------- --------
The Lion King $ 0.00
Tumbleweed Con... Elton John $ 123.32
Photographs & ... Jim Croce $ 4.95
Heads & Tales Harry Chapin $ 12.50
---------------------------------------------
$ 140.77
</PRE>
</BLOCKQUOTE>
<P>
The contents of <TT>FORMAT.RPT</TT>
are identical to the display created by the program in Listing
11.7.
<P>
The statement that changes a default file handle and format name
is a little complicated. Let's take a closer look at it.
<BLOCKQUOTE>
<PRE>
select((select(CD_REPORT), $~ = "CD_REPORT_TOTAL")[0]);
</PRE>
</BLOCKQUOTE>
<P>
In order to understand most statements, you need to look at the
innermost parenthesis first, and this one is no different. The
innermost expression to evaluate is
<BLOCKQUOTE>
<PRE>
select(CD_REPORT), $~ = "CD_REPORT_TOTAL"
</PRE>
</BLOCKQUOTE>
<P>
You might recall that the comma operator lets you place one or
more statements where normally you can place only one. That's
what is happening here. First, <TT>CD_REPORT</TT>
is selected as the default file handle for the <TT>print</TT>
and <TT>write</TT> statements, and
then the <TT>$~</TT> variable is changed
to the new format name. By eNClosing the two statements inside
parentheses, their return values are used in an array context.
You probably already have guessed that the <TT>[0]</TT>
notation then is used to retrieve the first element of the array:
the value returned from the <TT>select()</TT>
fuNCtion. Because the <TT>select()</TT>
fuNCtion returns the value of the previous default file handle,
after executing the second <TT>select()</TT>,
the default file handle is restored to its previous value.
<P>
This bit of code could have been written like this:
<BLOCKQUOTE>
<PRE>
$oldhandle = select(CD_REPORT);
$~ = "CD_REPORT_TOTAL";
select($oldhandle);
</PRE>
</BLOCKQUOTE>
<H2><A NAME="Summary"><FONT SIZE=5 COLOR=#FF0000>
Summary</FONT></A></H2>
<P>
In this chapter, you learned how to create simple reports that
iNCorporate headers, footers, and detail lines. Headers are used
at the top of each page and can consist of both static text and
values from variables. Footers are used at the bottom of each
page and can consist only of static text. Detail lines make up
the body of a report.
<P>
Header and detail lines are defined by using <TT>format</TT>
statements that have alternating field and value lines. The field
lines hold the static text and field holders while the value lines
hold a comma-delimited list of expressions.
<P>
You can use several different format characters when creating
the field holder to have left-justified, right-justified, or centered
fields. You also can use word-wrapping to display long pieces
of text in your reports.
<P>
Directing a report to a file instead of to <TT>STDOUT</TT>
requires some simple steps. The output file needs to be opened;
the file handle needs to be specified as the format name in the
<TT>format</TT> statement; the format
name needs to be specified in the <TT>write</TT>
statement; and the output file needs to be closed.
<P>
The next chapter focuses on special variables. All the different
special variables you have seen so far-and more-are discussed
along with some examples of how to use them.
<H2><A NAME="ReviewQuestions"><FONT SIZE=5 COLOR=#FF0000>
Review Questions</FONT></A></H2>
<P>
Answers to Review Questions are in Appendix A.
<OL>
<LI>What is the syntax of the <TT>format</TT>
statement?
<LI>What is a footer?
<LI>What fuNCtion is used to invoke the <TT>format</TT>
statement?
<LI>How can you change a detail format line into a header format
line?
<LI>What is the <TT>></TT> format
character used for?
<LI>What is the <TT>$^L</TT> variable
used for?
<LI>Can associative array variables be used in value lines?
<LI>What will the following line of code do?<BR>
<BR>
<TT>select((select(ANNUAL_RPT), $^ = "REGIONAL_SALES")[0]);</TT>
</OL>
<H2><A NAME="ReviewExercises"><FONT SIZE=5 COLOR=#FF0000>
Review Exercises</FONT></A></H2>
<OL>
<LI>Modify the program in Listing 11.4 to display the second field
as left-justified instead of right-justified.
<LI>Create a report that has both a price and a tax column. Use
a tax rate of seven percent.
<LI>Modify the program in Listing 11.7 to display an average of
the CD prices instead of the total of the prices.
<LI>Create a program that sends the report in the preceding exercise
to a file. Use the <TT>select</TT>
statement to change the default file handle so that a file handle
does not need to be passed to the <TT>write()</TT>
fuNCtion.
<LI>Modify Listing 11.5 so that each pass through the loop checks
the value of <TT>$-</TT>. When the
value of <TT>$-</TT> is one less than
<TT>$=</TT>, change the value of <TT>$^L</TT>
to emulate a footer with variable text.
<LI>Create a report that uses a detail line format with more than
one line. How would this affect the program written for Exercise
5?
</OL>
<HR>
<CENTER><P><A HREF="ch10.htm" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/ch10.htm"><IMG SRC="pc.gif" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/pc.gif" BORDER=0 HEIGHT=88 WIDTH=140></A>
<A HREF="#CONTENTS"><IMG SRC="cc.gif" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/cc.gif" BORDER=0 HEIGHT=88 WIDTH=140></A>
<A HREF="index-1.htm" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/index-1.htm"><IMG SRC="hb.gif" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/hb.gif" BORDER=0 HEIGHT=88 WIDTH=140></A>
<A HREF="ch12.htm" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/ch12.htm"><IMG SRC="nc.gif" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/nc.gif" BORDER=0 HEIGHT=88 WIDTH=140></A>
<HR WIDTH="100%"></P></CENTER>
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -