perl系列:出错的perl程序

perl系列:出错的perl程序,第1张

概述该博文将陆续列出本人编程过程中出现一些错误,供大家参考。 1、输出相反字符串 $a="abcde"; print reverse($a), "\n";    #输出“abcde” 原因:print要求列表,因此reverse把$a当作包含一个元素的列表,即($a),然后把该列表所有元素以相反顺序返回。但由于该列表只有一个元素,因此返回结果和原列表相同。 修正:使其处于标量上下文环境。方法至少有两个

该博文将陆续列出本人编程过程中出现一些错误,供大家参考。

1、输出相反字符串
$a="abcde";
print reverse($a),"\n";    #输出“abcde”
原因:print要求列表,因此reverse把$a当作包含一个元素的列表,即($a),然后把该列表所有元素以相反顺序返回。但由于该列表只有一个元素,因此返回结果和原列表相同。
修正:使其处于标量上下文环境。方法至少有两个。
print scalar reverse($a),"\n";    #使用scalar强行规定标量上下文
print reverse($a)."\n";    #使用字符串连接符将其置于标量上下文

2、逻辑 *** 作符的短路 *** 作
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";    #个人认为这个更好

3、比较 *** 作符的正确使用
if (a == b) {print "true\n";} else {print "false\n";}    #输出true
原因:'=='用于数字比较,字符比较应使用'eq'
修正:
if (a eq b) {print "true\n";} else {print "false\n";}    #输出false
    #这个错误原因很简单,但犯了不止一次错误
    #在这里经常犯的另一个错误是把'=='写成'='

4、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循环之后使用$_

5、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时,会有警告信息。

6、print的一个“异常”
环境:ubuntu12.04.1,perl 5.14.2,GNOME终端3.4.1.1
for (0..9) {
    print $_;
    sleep 1;    #暂停1s
    }
    #10s内看不到任何输出,10s后一次性输出0123456789
原因:命令行窗口一次输出一行,而在循环结束以前这一行没有结束
    因此直到循环结束,才一次性输出
修正:这个应该不是perl的问题
    若想每个循环都有输出,加一个换行符即可。

7、windows下文本文件多余的回车符
windows下文本文件的行尾是“\r\n",而chomp只能去掉最后的"\n"。
可使用"s/\r//"将所有的"\r"删掉。

8、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。

9、文件句柄没有关闭导致的错误
程序:
    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

10、正则表达式非贪心匹配的误用
程序:
    my $_="123-456-789";
    my $b=$1 if /-(.+?)$/;    #想匹配789
    print "$b\n";    #输出456-789
原因:正则表达式从左往右匹配,先找到第一个'-',然后逐个字符匹配直到字符串结尾
修正:my $b=$1 if /.+-(.+?)$/;

11、三目 *** 作符(条件 *** 作符)的误用 程序:     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);

总结

以上是内存溢出为你收集整理的perl系列:出错的perl程序全部内容,希望文章能够帮你解决perl系列:出错的perl程序所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1292583.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-10
下一篇 2022-06-10

发表评论

登录后才能评论

评论列表(0条)

保存