我试图在Perl中使用一个while
循环,该循环从命令行获取一个参数,这是要在字符串上打印的问候数。我写了以下内容:
# Basic settings to catch errors
use strict;
use warnings;
# Define subroutine containing the program
sub WhileNumbers {
# read script arguments
my $numberOfhellos = @ARGV;
chomp($numberOfhellos);
# Loop through the files
my $counts = 1;
while($counts <= $numberOfhellos) {
# Get user input the protein of interest
print ("Hello number $counts \n");
$counts ++;
}
}
# Calling the subroutine
WhileNumbers();
当我跑步时:
$ perl hellos.pl 3
我得到输出:
你好1号
实际上,我想要:
你好1号
你好2号
你好3号
任何线索为何while循环未按预期工作?
答案 0 :(得分:3)
问题在这里:
my $numberOfhellos = @ARGV;
您正在将数组分配给标量变量。这就是数组中元素的数量。由于您要将单个参数(3
)传递给脚本,即
@ARGV = ("3")
这会将$numberOfHellos
设置为1
。
解决方法是将$numberOfhellos
设置为@ARGV
的第一个元素,如下所示:
my $numberOfhellos = $ARGV[0];
或者,
my ($numberOfhellos) = @ARGV;
(由于括号)执行列表分配,该列表将@ARGV
的第一个元素存储在左侧列表的第一个元素中,即它也最终设置了$numberOfhellos = $ARGV[0]
此外,您不需要此:
chomp($numberOfhellos);
chomp
用于从readline
函数返回的字符串中删除结尾的换行符。这里没有换行符。
也就是说,在Perl中编写计数循环的一种更惯用的方法是使用for
(和一个范围)而不是while
:
my $numberOfHellos = $ARGV[0];
for my $count (1 .. $numberOfHellos) {
print "Hello number $count\n";
}
答案 1 :(得分:1)
这样做的时候
... my $numberOfhellos = @ARGV; ...
使用标量上下文,并且$numberOfhellos
获取分配的@ARGV
中的元素数,如果您传递了一个参数,则为1
。
将第一个元素明确分配给变量。
...
my $numberOfhellos = $ARGV[0];
...
那里也不需要chomp()
。您可能会将@ARGV
与<STDIN>
或类似的名称混淆。但是检查参数是否符合您的期望并没有什么害处。那就是检查他们的数字,如果第一个是整数。像这样:
...
my $numberOfhellos;
if (scalar(@ARGV) == 1
&& $ARGV[0] =~ m/\A[0-9]+\z/) {
$numberOfhellos = $ARGV[0];
}
else {
die("Wrong arguments");
}
...
请注意,scalar(@ARGV)
强制在@ARGV
上使用标量上下文,从而导致其元素数量增加。即原来的任务也一样。