欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

第十章 格式化輸出

by flamephoenix

一、定義打印格式
二、顯示打印格式
三、在打印格式中顯示值
  1、通用的打印格式
  2、格式和局域變量
  3、選擇值域格式
  4、輸出值域字符
四、輸出到其它文件
五、分頁(yè)
六、格式化長(zhǎng)字符串
七、用printf格式化輸出

    我們已經(jīng)見(jiàn)過(guò)用print函數(shù)將原始的未格式化的文本輸出到文件,本章講述如何用函數(shù)write和打印格式來(lái)生成格式化的輸出。
一、定義打印格式
    定義打印格式的關(guān)鍵字為format,語(yǔ)法為:
format formatname =
lines_of_output
.
    打印格式名formatname的命名規(guī)則與一般變量相同。結(jié)束行為一個(gè)句號(hào),此行不能有任何其它字符,包括空格,句號(hào)必須是該行第一個(gè)字符。
    打印格式的定義象子程序一樣可以放在任何地方,甚至可以放在條件語(yǔ)句中,但是最好把它們集中放在程序的開(kāi)頭或結(jié)尾。
二、顯示打印格式
    打印格式的顯示有兩步:
     1、將系統(tǒng)變量$~設(shè)成所要使用的格式
     2、調(diào)用函數(shù)write
    例如:
1 : #!/usr/local/bin/perl
2 :
3 : $~ = "MYFORMAT";
4 : write;
5 :
6 : format MYFORMAT =
7 : ===================================
8 : Here is the text I want to display.
9 : ===================================
10: .
    結(jié)果輸出如下:
$ program
===================================
Here is the text I want to display.
===================================
$
    如果不用$~指定打印格式,Perl解釋器就假定要使用的格式名與要寫入的文件變量同名,在本例中,如果不指定使用MYFORMAT,則Perl解釋器試圖使用名為STDOUT的打印格式。
三、在打印格式中顯示值
    我們使用打印格式的主要原因當(dāng)然是格式化存貯在簡(jiǎn)單變量或數(shù)組變量中的值從而生成可讀性好的輸出,這一目的用“值域”來(lái)實(shí)現(xiàn)。每個(gè)值域指定一個(gè)值,如變量或表達(dá)式,調(diào)用write函數(shù)時(shí),該值就以值域指定的格式顯示。
1、通用的打印格式
    打印格式的一個(gè)缺點(diǎn)是定義中包含了變量名,例如:
format MYFORMAT =
==========================================================
The winning number is @<<<<<<!
$winnum
==========================================================
.
    當(dāng)調(diào)用write輸出此格式時(shí),必須記著它使用了變量$winnum。用子程序和局域變量就可以創(chuàng)建更通用的打印格式。下例從STDIN輸入一個(gè)文件并輸出五個(gè)出現(xiàn)頻率最高的字母及出現(xiàn)次數(shù)。
1 : #!/usr/local/bin/perl
2 :
3 : while ($line = ) {
4 :   $line =~ tr/A-Z/a-z/;
5 :   $line =~ s/[^a-z]//g;
6 :   @letters = split(//, $line);
7 :   foreach $letter (@letters) {
8 :     $lettercount{$letter} += 1;
9 :   }
10: }
11:
12: $~ = "WRITEHEADER";
13: write;
14: $count = 0;
15: foreach $letter (reverse sort occurrences
16:       (keys(%lettercount))) {
17:   &write_letter($letter, $lettercount{$letter});
18:   last if (++$count == 5);
19: }
20:
21: sub occurrences {
22:   $lettercount{$a} <=> $lettercount{$b};
23: }
24: sub write_letter {
25:   local($letter, $value) = @_;
26:
27:   $~ = "WRITELETTER";
28:   write;
29: }
30: format WRITEHEADER =
31: The five most frequently occurring letters are:
32: .
33: format WRITELETTER =
34:   @: @<<<<<<
35:   $letter, $value
36: .
    運(yùn)行結(jié)果如下:
$ program
This is a test file.
This test file contains some input.
The quick brown fox jumped over the lazy dog.
^D
The five most frequently occurring letters are:
        t: 10
        e: 9
        i: 8
        s: 7
        o: 6
$
2、格式和局域變量
    在上例中,你可能已經(jīng)注意到子程序write_letter調(diào)用write輸出字母及其出現(xiàn)次數(shù),即使格式定義在子程序外部仍能正常工作。在第17行中將字母及其出現(xiàn)次數(shù)傳遞給該子程序,在子程序中,打印格式使用局域變量$letter和$value,這樣保證了在foreach循環(huán)中每次輸出當(dāng)前的字母和值。
    然而要注意的是,使用my定義的局域變量要求格式定義在子程序內(nèi)部,否則就不會(huì)輸出,因此,用write輸出的局域變量一定要用local定義。(local和my詳見(jiàn)《子程序》一章)
    注:Perl4中沒(méi)有my函數(shù),故不會(huì)有此問(wèn)題。
3、選擇值域格式
    我們已經(jīng)知道了打印格式和write函數(shù)怎么工作,現(xiàn)在來(lái)看看值域的格式,見(jiàn)下表:

格式 值域含義
@<<< 左對(duì)齊輸出
@>>> 右對(duì)齊輸出
@||| 中對(duì)齊輸出
@##.##   固定精度數(shù)字  
@* 多行文本

    每個(gè)值域的第一個(gè)字符是行填充符,當(dāng)使用@字符時(shí),不做文本格式化。對(duì)文本的格式化稍后來(lái)講。
    在上表中,除了多行值域@*,域?qū)挾嫉扔谄渲付ǖ陌址鸃在內(nèi)的字符個(gè)數(shù),例如:
     @###.##
    表示七個(gè)字符寬,小數(shù)點(diǎn)前四個(gè),小數(shù)點(diǎn)后兩個(gè)。
4、輸出值域字符
    在打印格式里,特定字符如@、<和>被看作值域定義,那么如何將它們輸出呢?方法如下:
format SPECIAL =
This line contains the special character @.
"@"
.
四、輸出到其它文件
    缺省地,函數(shù)write將結(jié)果輸出到標(biāo)準(zhǔn)輸出文件STDOUT,我們也可以使它將結(jié)果輸出到任意其它的文件中。最簡(jiǎn)單的方法就是把文件變量作為參數(shù)傳遞給write,如:
     write (MYFILE);
    這樣,write就用缺省的名為MYFILE的打印格式輸出到文件MYFILE中,但是這樣就不能用$~變量來(lái)改變所使用的打印格式。系統(tǒng)變量$~只對(duì)缺省文件變量起作用,我們可以改變?nèi)笔∥募兞,改?~,再調(diào)用write,例如:
     select (MYFILE);
     $~ = "MYFORMAT";
     write;
    當(dāng)select改變?nèi)笔∥募兞繒r(shí),它返回當(dāng)前缺省文件變量的內(nèi)部表示,這樣我們就可以創(chuàng)建子程序,按自己的想法輸出,又不影響程序的其它部分,如下:
sub write_to_stdout {
  local ($savefile, $saveformat);
  $savefile = select(STDOUT);
  $saveformat = $~;
  $~ = "MYFORMAT";
  write;
  $~ = $saveformat;
  select($savefile);
}
五、分頁(yè)
    在輸出到打印機(jī)時(shí),可以在每頁(yè)頂部輸出相應(yīng)的信息,這樣的特殊文本叫頁(yè)眉。定義頁(yè)眉實(shí)際上就是定義名為filename_TOP的打印格式,例如給標(biāo)準(zhǔn)輸出文件定義頁(yè)眉如下:
     format STDOUT_TOP =
     Consolidated Widgets Inc. 1994 Annual Report
     .
    在頁(yè)眉的定義中也可以包含值域,頁(yè)眉中經(jīng)常使用的一個(gè)特殊值是當(dāng)前頁(yè)碼,存貯在系統(tǒng)變量$%中,如:
     format STDOUT_TOP =
     Page @<<.
     $%
     .
    我們也可以通過(guò)改變系統(tǒng)變量$^改變定義頁(yè)眉的打印格式名,與$~一樣,$^只對(duì)當(dāng)前缺省文件起作用,因此可以與select函數(shù)結(jié)合使用。
    缺省情況下,每頁(yè)長(zhǎng)度為60行,可以通過(guò)改變$=來(lái)改變頁(yè)長(zhǎng),如:
     $= = 66; #頁(yè)長(zhǎng)設(shè)為66行
    此賦值語(yǔ)句必須出現(xiàn)在第一個(gè)write語(yǔ)句前。
    注:一般使用分頁(yè)機(jī)制時(shí)不用print函數(shù),因?yàn)楫?dāng)用write輸出時(shí),Perl解釋器跟蹤每頁(yè)的當(dāng)前行號(hào)。如果必須使用print而又不打亂頁(yè)計(jì)數(shù),可以調(diào)整系統(tǒng)變量$-。$-的含義是當(dāng)前行到頁(yè)末之間的行數(shù),當(dāng)$-達(dá)到零時(shí),就開(kāi)始新的一頁(yè),調(diào)整方法如:
     print ("Here is a line of output\n");
     $- -= 1;
六、格式化長(zhǎng)字符串
    我們已經(jīng)學(xué)過(guò)值域@*可以輸出多行文本,但它完全將字符串原樣輸出,不加以格式化。在Perl中對(duì)長(zhǎng)字符串(包含換行)進(jìn)行格式化的值域定義很簡(jiǎn)單,只需把打頭的@字符換成^就行了,這種文本格式化中,Perl解釋器在一行中放置盡可能多的單詞。每當(dāng)輸出一行文本,被輸出的子串就從變量中刪除,再次在域值中使用該變量就把剩下的字符串繼續(xù)按格式輸出。當(dāng)內(nèi)容已輸出完畢,該變量就成了空串,再輸出就會(huì)輸出空行,為避免輸出空行,可以在值域格式行首加一個(gè)~字符。見(jiàn)下例:
1 : #!/usr/local/bin/perl
2 :
3 : @quotation = <STDIN>;
4 : $quotation = join("", @quotation);
5 : $~ = "QUOTATION";
6 : write;
7 :
8 : format QUOTATION =
9 : Quotation for the day:
10: -----------------------------
11: ~  ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
12: $quotation
13: ~  ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
14: $quotation
15: ~  ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
16: $quotation
17: -----------------------------
18: .
    運(yùn)行結(jié)果如下:
$ program
Any sufficiently advanced programming
language is indistinguishable from magic.
^D
Quotation for the day:
-----------------------------
   Any sufficiently advanced programming language is
   indistinguishable from magic.
-----------------------------
$
    如果把打印格式中行首的~字符去掉,上面的輸出結(jié)果中就會(huì)多一行空行。很明顯,當(dāng)字符串長(zhǎng)度不明確時(shí),這種用法很不方便,原因就在于它指明了輸出的行數(shù)上限,超過(guò)這一上限的字符就不會(huì)被輸出,解決方法很簡(jiǎn)單,就是在域值格式行首加兩個(gè)~字符,這樣就會(huì)持續(xù)按格式輸出文本直到輸出完畢,用此方法把上述程序改寫如下:
1 : #!/usr/local/bin/perl
2 :
3 : @quotation = <STDIN>;
4 : $quotation = join("", @quotation);
5 : $~ = "QUOTATION";
6 : write;
7 :
8 : format QUOTATION =
9 : Quotation for the day:
10: -----------------------------
11: ~~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
12: $quotation
13: -----------------------------
14: .
    這樣運(yùn)行結(jié)果相同。
七、用printf格式化輸出
    還有一種容易掌握和使用的格式化輸出函數(shù),那就是printf,它與C語(yǔ)言中的printf基本上是相同的。printf有兩個(gè)參數(shù),一個(gè)是字符串,其中含有一個(gè)或多個(gè)域值形式,另一個(gè)是與各域值相對(duì)應(yīng)的變量值按一定格式替換,如:
     printf("The number I want to print is %d.\n", $number);
    各種域值形式如下表:

域值   含義
%c 單個(gè)字符
%d 十進(jìn)制整數(shù)
%e 科學(xué)計(jì)數(shù)法形式的浮點(diǎn)數(shù)  
%f 普通形式(定點(diǎn))浮點(diǎn)數(shù)
%g 緊縮形式浮點(diǎn)數(shù)
%o 八進(jìn)制整數(shù)
%s 字符串
%u 無(wú)符號(hào)整數(shù)
%x 十六進(jìn)制整數(shù)

    一些使用細(xì)節(jié)如下:
1、在格式d、o、u或x中,如果整數(shù)值較大或可能較大,可加個(gè)l字符,意為長(zhǎng)整型,如%ld。
2、%字符后加正整數(shù)表示該域的最小寬度,如果輸出結(jié)果寬度不足,則向右對(duì)齊,前面用空格補(bǔ)足,如果該正整數(shù)以數(shù)字0打頭,則補(bǔ)足字符為0。若%字符后為負(fù)整數(shù),則結(jié)果向右對(duì)齊。
3、浮點(diǎn)數(shù)域值(%c、%f和%g)中可以指定小數(shù)點(diǎn)前后的寬度,如%8.3f意為總寬度為8個(gè)字符,小數(shù)點(diǎn)后(即小數(shù)部分)為3個(gè)字符,多出的小數(shù)部分四舍五入。
4、在整數(shù)、字符或字符串的值域中使用如上的小數(shù)形式n.m,整數(shù)部分n為總寬度,小數(shù)部分m為輸出結(jié)果的最大寬度,這樣就保證了輸出結(jié)果前至少有n-m個(gè)空格。

上一章 下一章 目錄