【问题标题】:Perl using varying elements in an array for a user option menuPerl 使用数组中的不同元素作为用户选项菜单
【发布时间】:2013-01-23 21:43:10
【问题描述】:

我有一个名为@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]

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

我知道我可以使用 如果 STDIN 匹配 dog 则执行此操作,如果它匹配大象则执行此操作,依此类推

我真正寻找的是建议人们认为是最佳/最有效/最可接受/专业/首选/聪明的不同方法。

【问题讨论】:

  • 小心这样的问题——它们有被关闭并归类为“不具建设性”的危险:就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、参考资料或特定专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。
  • 你看过 CPAN 的菜单驱动系统吗?
  • @Jonathan Leffler - 是的,我看过 CPAN,那里有许多解决方案,但理想情况下我正在寻找最好的方法,而不必使用模块,也感谢您的建议。

标签: arrays perl data-structures menu


【解决方案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"));

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

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

如果您将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 &lt; $selection ) &amp;&amp; ( scalar(@_) &gt;= $selection)) 是为了确保输入在给定的选择范围内。选择应该大于零并且小于或等于选择的项目数,这是scalar(@_) 返回的(@_ 是指传递给例程的参数,标量函数返回的数量数组中的项目)。

【讨论】:

  • 非常感谢您的回答,这正是我所需要的。您能否更详细地向我解释以下几行的作用,它们是 'printf " %4d) %s\n",$lcv,$_[$lcv-1];'和'( 0 = $selection))',因为我有点不确定,谢谢你的帮助
  • 我的答案不适合评论,所以我将它添加到上面的答案中。很高兴为您提供帮助。
  • 非常感谢您对我的帮助很大,您解释得很好,再次感谢。
【解决方案2】:

您需要进行一些验证。

for my $id (1 .. scalar @options) {
  my $element = $options[$id - 1];
  say "$id: $element";
}
my $input = <STDIN>;
my $selection = $options[$input - 1];

【讨论】:

  • 谢谢,这正是我一直在寻找的那种东西,你会认为这是做这种事情的首选方法,还是只是众多选择之一?
  • 当您提到“您需要进行一些验证”时,您指的是什么?谢谢。
  • 这是你能得到的最基础的——迭代数组中的元素数量,打印出 id 和元素数量,然后通过索引获取选择。 (移一位,因为索引从 0 开始计数,id 通常从 1 开始计数)
  • 例如,他们没有输入“asdf”,如果是,则处理重新提示。
  • 谢谢,刚刚回答了我的问题,我明白你的意思了。
【解决方案3】:

我会建议类似的东西

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];
}

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

【讨论】:

  • 谢谢,这也是我一直在寻找的东西,会试试看。
猜你喜欢
  • 2018-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-26
  • 2020-05-21
  • 2021-01-16
  • 1970-01-01
  • 2022-11-01
相关资源
最近更新 更多