加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

perl系列:出错的perl程序

发布时间:2020-12-15 21:00:56 所属栏目:大数据 来源:网络整理
导读:该博文将陆续列出本人编程过程中出现一些错误,供大家参考。 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 "truen";} else {print "falsen";}??? #输出true
原因:'=='用于数字比较,字符比较应使用'eq'
修正:
if (a eq b) {print "truen";} else {print "falsen";}??? #输出false
??? #这个错误原因很简单,但犯了不止一次错误
??? #在这里经常犯的另一个错误是把'=='写成'='

4、while循环对$_的影响1
my @a=1..5;
for (@a) {
?? ?open FILEIN,'< ../temp';
?? ?while (<FILEIN>) {/A/;}
?? ?$_++;
?? ?}
print "@an";??? #输出"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-endn";??? #输出"???????? -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下文本文件的行尾是“rn",而chomp只能去掉最后的"n"。
可使用"s/r//"将所有的"r"删掉。

8、shift的误用
@a=1..10;
$a=shift @a if shift @a;
print "$an";??? #输出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 "yesn" : print "nulln";??? #输出null
原因:Fout没有关闭,所以print的输出还没有及时写入文件,导致Fin调用时找不到内容。
修正:
方法1:及时关闭Fout。
??? open Fout,'> temp';
?? ?print Fout 1..10;
?? ?close Fout;
?? ?open Fin,'< temp';
?? ?my $a = <Fin>;
?? ?$a? print "yesn" : print "nulln";??? #输出yes
方法2:两个句柄同名
??? open Fout,'> temp';
?? ?print Fout 'a' x 10;
?? ?open Fout,'< temp';
?? ?my $a = <Fout>;
?? ?$a? print "yesn" : print "nulln";??? #输出yes
注意:前面程序中,由于往程序中写入内容较少,所以全部内容都没有写入。但当写入内容非常多时,会写入部分内容,导致容易判断错误。
??? open Fout,'> temp';
?? ?print Fout 'a' x 100000;
?? ?open Fin,'< temp';
?? ?my $a = <Fin>;
?? ?$a? print "yesn" : print "nulln";??? #输出yes
?? ?print length($a),"n"??? #输入98304

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

11、三目操作符(条件操作符)的误用 程序: ????my $a=1; ?? ?$a? $a += 2 : $a -= 3; ?? ?print "$an";??? 输出0 原因:三目操作符的结果可以赋值,如$a>$b? $a : $b = 0;(将较大的数赋值为0) ??? 因此原程序中的 ‘$a? $a += 2 : $a -= 3;’ 相当于 ‘($a? $a += 2 : $a) -= 3;’ 修正:$a? ($a += 2) : ($a -= 3);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读