perl系列:出錯的perl程序

該博文將陸續列出本人編程過程當中出現一些錯誤,供你們參考。 正則表達式

一、輸出相反字符串
$a="abcde";
print reverse($a), "\n";    #輸出「abcde」
緣由:print要求列表,所以reverse把$a看成包含一個元素的列表,即($a),而後把該列表全部元素以相反順序返回。但因爲該列表只有一個元素,所以返回結果和原列表相同。
修正:使其處於標量上下文環境。方法至少有兩個。
print scalar reverse($a), "\n";    #使用scalar強行規定標量上下文
print reverse($a)."\n";    #使用字符串鏈接符將其置於標量上下文 編程

二、邏輯操做符的短路操做
opendir D1, "test" || die "no exist";    #當test不存在時,並無輸出出錯信息
緣由:"||"的優先級比較高,原句至關於opendir D1, ("test" || die "no exist");
修正:使用括號或使用or
opendir (D1, "test") || die "no exist";
opendir D1, "test" or die "no exist";    #我的認爲這個更好 ubuntu

三、比較操做符的正確使用
if (a == b) {print "true\n";} else {print "false\n";}    #輸出true
緣由:'=='用於數字比較,字符比較應使用'eq'
修正:
if (a eq b) {print "true\n";} else {print "false\n";}    #輸出false
    #這個錯誤緣由很簡單,但犯了不止一次錯誤
    #在這裏常常犯的另外一個錯誤是把'=='寫成'=' windows

四、while循環對$_的影響1
my @a=1..5;
for (@a) {
    open FILEIN, '< ../temp';
    while (<FILEIN>) {/A/;}
    $_++;
    }
print "@a\n";    #輸出"1 1 1 1 1"
緣由:多是while循環後沒有將$_恢復原值
    將while換成for,則輸出"2 3 4 5 6"
    不知道算不算bug
修正:根據具體狀況有多種修正方式
    但最保險的是不要在while循環以後使用$_ 命令行

五、while循環對$_的影響2
my @a=0..9;
print @a,"\n";    #輸出"0123456789"
&Read(@a);
print "@a-end\n";    #輸出"         -end"
sub Read {
    for (@_) {
        open FILE, '< temp';
        /A/ while <FILE>;
        }
    }
緣由:仍然是while循環後$_沒有恢復原值,而while最後讀取的是結束標誌
    同時$_和@_又能夠直接修改調用參數
修正:除非要修改調用參數
    不然最好在子程序開始的時候將@_的內容賦予其餘變量
另:在使用use warnings時,會有警告信息。 scala

六、print的一個「異常」
環境:ubuntu12.04.1, perl 5.14.2, GNOME終端3.4.1.1
for (0..9) {
    print $_;
    sleep 1;    #暫停1s
    }
    #10s內看不到任何輸出,10s後一次性輸出0123456789
緣由:命令行窗口一次輸出一行,而在循環結束之前這一行沒有結束
    所以直到循環結束,才一次性輸出
修正:這個應該不是perl的問題
    若想每一個循環都有輸出,加一個換行符便可。 字符串

七、windows下文本文件多餘的回車符
windows下文本文件的行尾是「\r\n",而chomp只能去掉最後的"\n"。
可以使用"s/\r//"將全部的"\r"刪掉。 test

八、shift的誤用
@a=1..10;
$a=shift @a if shift @a;
print "$a\n";    #輸出2
緣由:本意是若是能從@a中去除元素,則輸出該元素。
    但其實是對@a進行了兩次shift操做。
修正:$a=shift @a if @a;
    該錯誤一樣適用於pop、push、unshift。 變量

九、文件句柄沒有關閉致使的錯誤
程序:
    open Fout, '> temp';
    print Fout 1..10;
    open Fin, '< temp';
    my $a = <Fin>;
    $a? print "yes\n" : print "null\n";    #輸出null
緣由:Fout沒有關閉,因此print的輸出尚未及時寫入文件,致使Fin調用時找不到內容。
修正:
方法1:及時關閉Fout。
    open Fout, '> temp';
    print Fout 1..10;
    close Fout;
    open Fin, '< temp';
    my $a = <Fin>;
    $a? print "yes\n" : print "null\n";    #輸出yes
方法2:兩個句柄同名
    open Fout, '> temp';
    print Fout 'a' x 10;
    open Fout, '< temp';
    my $a = <Fout>;
    $a? print "yes\n" : print "null\n";    #輸出yes
注意:前面程序中,因爲往程序中寫入內容較少,因此所有內容都沒有寫入。但當寫入內容很是多時,會寫入部份內容,致使容易判斷錯誤。
    open Fout, '> temp';
    print Fout 'a' x 100000;
    open Fin, '< temp';
    my $a = <Fin>;
    $a? print "yes\n" : print "null\n";    #輸出yes
    print length($a),"\n"    #輸入98304 perl

十、正則表達式非貪心匹配的誤用
程序:
    my $_="123-456-789";
    my $b=$1 if /-(.+?)$/;    #想匹配789
    print "$b\n";    #輸出456-789
緣由:正則表達式從左往右匹配,先找到第一個'-',而後逐個字符匹配直到字符串結尾
修正:my $b=$1 if /.+-(.+?)$/;

十一、三目操做符(條件操做符)的誤用 程序:     my $a=1;     $a? $a += 2 : $a -= 3;     print "$a\n";    輸出0 緣由:三目操做符的結果能夠賦值,如$a>$b? $a : $b = 0;(將較大的數賦值爲0)     所以原程序中的 ‘$a? $a += 2 : $a -= 3;’ 至關於 ‘($a? $a += 2 : $a) -= 3;’ 修正:$a? ($a += 2) : ($a -= 3);

相關文章
相關標籤/搜索