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);

相关文章
相关标签/搜索