Perl入門筆記——輸入和輸出

Learning Perl 

第五章 輸入和輸出
讀取標準輸入,使用行操做符<STDIN>:
$line = <STDIN>;
chomp($line);
若是讀到文件結尾,行輸入符就會返回undef.
while (defined($line=<STDIN>)) {
  print "I have seen $line.\n";
}
Perl能夠將上述定義簡寫:
while (<STDIN>) {
    print "I have seen $_.\n";
}
行輸入操做符<STDIN>與默認變量($_)之間沒有關聯,只是這個簡寫裏,輸入的內容剛好存儲在默認變量裏面。
for與while的區別,while循環,Perl會讀取一行,而後在尋找其餘輸入行;
for循環會將輸入所有讀起來。

另一種讀取輸入的方法,就是使用鑽石操做符<>,它能讓程序在處理參數時,提供相似Unix工具的功能。
程序調用參數(invocation argument)一般是命令行上跟着程序後面的幾個單詞。
$./my_program.pl cao qing
若是把連字符看成參數,則表示從標準輸入讀取數據。假如調用參數cao-qing。程序會先處理cao,而後處理標準輸入流中提供的數據,最後纔是qing。
能夠在程序運行時指定程序的輸入源。
鑽石操做符是行輸入操做符的特例。他不是從鍵盤取得輸入,而是從用戶指定位置讀取:
while (<>) {
    chomp;
    print "It was $_ that i saw.\n";
}
加入鑽石操做符沒法打開某個文件讀取其中內容時,會出現診斷錯誤。
鑽石操做符不會去檢查命令行參數,它的參數來自於@ARGV數組。該數組就是命令行參數列表。
@ARGV列表與其餘數組相似,進行一樣操做。若是爲空列表,則改用標準輸入流。
@ARGV = qw (cao qing wang huan);
while (<>) {
  chomp;
  print "I have seen $_.\n";
}
強制讓鑽石操做符讀取上述四個文件。

輸出到標準輸出
print操做符會讀取後續列表中的全部元素。
直接使用數組和使用數組內插是不一樣的:
print @array;
print "@array";
第一個會一個接一個的打印全部元素;第二個是打印一個字符串。
@array = qw \ cao qing wang huan\;
print @array;
print "\n";
print  "@array";

caoqingwanghuan
cao qing wang huan
print處理的是帶打印的字符串列表,因此他的參數在列表上下文執行。而鑽石操做符在列表上下文中返回許多輸入組成的列表,因此他們之間能夠配合工做。
print <>;        #Unix cat
print sort <>;    #Unix sort
print後面的括號無關緊要,除非會改變表達式的意義,不然Perl裏的括號能夠省略。
Perl能夠省略括號,可是不要忘記括號的歸屬,
printf格式化輸出
printf須要的參數包括格式化字符串和要輸出的數據列表。
元素個數應該和轉換的數目同樣多,不然沒法正常運行。
要輸出恰當的數組形式,可使用%g,它會自動選擇浮點數,整數甚至是指數形式。
print "%g %g %g\n", 5/2, 4, 2 ** 10;
%d表示十進制整數,它會無條件階段,而非四捨五入。
%s表明字符串,他的功能就是字符串內插。
若是寬帶字段爲負數,則會左對齊。
數組和printf。通常不會把數組看成printf參數。這是由於數組會包含任意數目的元素,而格式化字符串只會用到固定數目的元素。
能夠在程序中動態的產生格式字符串:
my @items = qw (cao qing wang huan);
my $format = "The items are: \n" . ("%10s\n" x @items);
print "The format is >>$format<<\n";
printf $format, @items;

The format is >>The items are: 
%10s
%10s
%10s
%10s
<<
The items are: 
       cao
      qing
      wang
      huan
注意上下文的重要性。

文件句柄
文件句柄(filehandle)就是程序裏表明Perl進程與外界之間的I/O聯繫的名稱。
能夠把文件句柄的引用放在常規的標量變量裏,不過喜歡使用裸字(bareword)。
建議使用全大寫字母來命名文件句柄。
Perl保留6個特殊文件句柄名:STDIN,STDOUT,STDERR,DATA,ARGV,ARGVOUT。
打開文件句柄
open CONF, 'dino';
open CONF, '< dino';
open CONF, '> fred';
open CONF, '>> logile';
第一行和第二行徹底相同,第三行爲打開一個文件句柄並輸出到新文件fred,第四行已追加的方式打開文件句柄。
可使用任意的一個標量表達式來代替文件名說明符。
注意大於號後面的空格。
新版的還能夠接受三個參數,open CONF, '<', 'dino';
能夠更容易區分模式和文件名自己。還有一個好處就是指定編碼值。
指定讀取的文件爲UTF-8編碼的:
open CONF, '<:encoding(utf-8)', 'dino';
除了編碼以外,數據輸入和輸出還有其餘層能夠控制數據轉換。
解決回車換行能夠藉助:crlf層
open BEDROCK, '>:crlf', $filename;
讀取DOS風格的文件時,能夠:open BEDROCK, "<:crlf", $filename
會自動轉換爲Unix風格的換行符。

以二進制方式讀取文件句柄
Perl5.6之後能夠在binmode的第二個參數位置指定層。若是但願輸出Unicode到STDOUT,就要確保STDOUT知道如何處理拿到的數據:
binmode STDOUT, ':encoding(UTF-8)';
若是知道傳入的是UTF-8編碼的字符:
binmode STDIN, ':encoding(UTF-8)';
有問題的文件句柄,可使用-w和warnings編譯指令來啓用警告功能。

關閉文件句柄
close BEDROCK;
die處理致命錯誤,能夠可以本身觸發致命錯誤並給出錯誤信息。
die函數會輸出指定信息到標準錯誤流,並終止程序,返回不爲0的狀態碼。
if (! open LOG, '>>', 'logfile') {
    die "cannot create logfile: $!";
}
open失敗,die會終止程序運行。$!就是可讀的系統錯誤信息。
能夠用warn發出警告信息,可是不會終止程序運行。
autodie編譯指令能夠自動檢測致命錯誤。
use autodie;
使用文件句柄
一旦文件句柄以讀取模式打開,即可以從他讀取一行行數據。
if (! open PASSWD, '<', '/etc/passwd') {
    die "How did you get logged in?($!)";
}
while (<PASSWD>) {
    chomp;
    ...
}
已寫入或者添加模式打開的文件句柄能夠在print或printf函數中使用。使用時,直接放在函數名以後,參數列表以前。
print LOG "I love you.\n";
print STDERR "I miss you.\n";
改變默認的文件句柄
select BEDROCK;
print "I hope you can love me.\n";
一旦選擇用了默認文件句柄,文件會一直往哪裏輸出。
select LOG;
$| = 1;
select STDOUT;
print LOG "i love you./n";
將數據輸出到文件句柄時,默認都會通過緩衝處理,可是隻要將默認變量$|設定爲1,就會是當前的默認文件句柄在每次輸出後馬上刷新緩衝區。
從新打開文件句柄。Perl從新打開文件句柄時,會默認關閉原來那個。
相關文章
相關標籤/搜索