0

我有一个名为的数组@option

每次运行脚本时,都@option可能包含不同的元素和不同数量的元素

脚本第一次运行时可能包含

狗, 猫, 羚羊, 象, 猪

第二次运行脚本时,它可能包含

马, 大象, 山羊

我需要什么: 使用数组中的元素,提示用户选择元素,方法是输入数组元素字符串或输入数组中每个元素链接的值,或者您能想到的任何其他更好的方法.

例如:

Please select which one you want to delete by entering its associated number:
dog[1] 
cat[2] 
antelope[3]
elephant[4]
pig[5]

(在用户选择一个之后,我的其余代码将做一些事情,然后将其删除)。

我知道我可以使用if STDIN 匹配 dog do this 来执行此操作,如果它匹配大象则执行 that 等等

我实际上正在寻找的是对人们认为是最好/最有效/最可接受/专业/首选/聪明的不同方法的建议。

4

3 回答 3

1

这是我想出的,它允许您有一个用于查询输入的字符串并检查以确保响应有效。如果没有,它将再次查询用户。该子例程返回所选数组项的索引。

sub displayMenu($@)
{
  # First item is the query string, so shift it 
  # from the inputs and save it 
  my $queryString = shift @_;
  # Loop control variable;
  my $lcv;
  # User selection of choices
  my $selection;
  # Flag to indicate you have the correct input
  my $notComplete = 1;

  # Clear some space on the screen
  print "\n" x 10;
  # Loop until you have an answer
  while ( $notComplete ) 
  {

    print "-" x 40 . "\n";
    for( $lcv = 1; $lcv <= scalar(@_) ; $lcv++ ) 
    {
      printf " %4d)  %s\n",$lcv,$_[$lcv-1];
    }
    print "\n";
    # Query for a response
    print "$queryString\n";
    # Get response
    $selection = <STDIN>;
    # Remove the carriage return
    chomp($selection);

    # Check to make sure it is string of digits
    # and it is within the range of the numbers
    # If it is, clear the not complete flag
    if (( $selection =~ m/^\d*/ ) && 
    ( 0 < $selection ) && ( scalar(@_) >= $selection)) 
    {
      $notComplete = 0;
    }
    # Else there is a error so try again
    else
    {
      print "\n" x 10;
      print "\nIncorrect Input.  Try again\n";
    }
  }

  # Return the index of the selected array item
  return ($selection - 1);
}

如何调用它的示例如下:

$returnValue = displayMenu("Enter number of the item you want to select",("Test1","Test2","Test3"));

调用中的第一项是要为选择的输入打印的字符串,然后是要从中选择的项数组。然后它从选择中返回索引。

从下面的评论中回答您的问题。我的回答是很想发表评论。

如果您将其分解为printf " %4d) %s\n",$lcv,$_[$lcv-1]多个部分,则 printf 用于格式化输出的功能。print if 的第一个参数是一个字符串,指示行的格式,后跟提供要格式化的值的项目。在这种情况下,%4d 是打印出一个整数,它应该在行上占据 4 个空格,而 %s 是打印出一个字符串。接下来的项目是格式说明符的参数,在这种情况下是 $lcv是选项的编号 (%4d) 并且$_[$lcv-1]是选项($lcv-1 是因为数组在从零开始的索引中,$_ 是访问传递给例程的参数。注意:我移动了第一个参数为 %s 传入的项以获得标题)。如果您查看http://perldoc.perl.org/functions/sprintf.html它给出了各种格式说明符的描述(sprintf 是打印到一个字符串,但格式说明符对于 printf 是相同的)。

( 0 < $selection ) && ( scalar(@_) >= $selection))是为了确保输入在给定的选择范围内。选择应该大于零并且小于或等于选择的项目数,这是scalar(@_)返回的(@_指的是传递给例程的参数,标量函数返回数组中的项目数)。

于 2013-01-24T05:08:24.343 回答
0

你需要做一些验证。

for my $id (1 .. scalar @options) {
  my $element = $options[$id - 1];
  say "$id: $element";
}
my $input = <STDIN>;
my $selection = $options[$input - 1];
于 2013-01-23T21:54:16.800 回答
0

我会建议像

sub get_user_selection {
  my(@choices) = @_;
  my $index = 1;
  for my $choice (@choices) {
    print "$index.) $choices[$index - 1]\n";
    $index++;
  }
  print "Enter your choice: ";
  return $choices[<STDIN> - 1];
}

该子程序将显示一个菜单,并返回用户通过输入数字选择的值。

于 2013-01-23T21:57:33.630 回答