while循环不循环经过1

时间:2019-05-25 16:17:04

标签: perl parameter-passing conditional-statements command-line-arguments

我试图在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循环未按预期工作?

2 个答案:

答案 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上使用标量上下文,从而导致其元素数量增加。即原来的任务也一样。