【问题标题】:Perl hash + while loopPerl 哈希 + while 循环
【发布时间】:2014-11-14 09:08:28
【问题描述】:

我是新来的,对编程很陌生。不管是好是坏,我决定使用 Perl 作为一种闯入编码的方式。

我的问题涉及以下 Perl 代码:

my $name;
my %phonenumbers = (
    "Gary" => "0001",
    "Ian"  => "0002",
    "Nick" => "0003",
);

my $numbers = reverse $name;

print "Whose phone number do you want?\n";
my $selection = <STDIN>;
while ( $selection ne $phonenumbers{$name} ) {
    chomp;
    print "$_ is not in my database. Try another name";
} else {
    print "$_: $phonenumbers{$name}";
}

我希望它留在循环中,并在给出不正确的名称时要求正确的名称。否则我希望它显示正确的电话号码。现在无论如何它都保持在循环中。

我尝试使用 if 和 until 代替,但没有运气。有人可以解释我缺少什么吗?

【问题讨论】:

  • 您只检查了一次&lt;STDIN&gt; - 您需要再次查询。
  • 阅读后立即选择,对于初学者

标签: perl hash while-loop


【解决方案1】:

如果输入符合您想要的条件,则创建一个无限循环并使用last 打破它。

use strict;
use warnings;

my %phonenumbers = (
    "Gary" => "0001",
    "Ian"  => "0002",
    "Nick" => "0003",
);

while (1) {
    print "Whose phone number do you want?\n";
    chomp( my $name = <STDIN> );

    if ( $phonenumbers{$name} ) {
        print "$name: $phonenumbers{$name}";
        last;
    } else {
        print "$name is not in my database. Try another name";
    }
}

【讨论】:

    【解决方案2】:

    如果你想反复询问号码,你需要将它包含在你的循环中;否则$selection 将永远不会从用户那里获得任何新值。我通常喜欢在这种情况下跳出的无限循环。另外,我认为你真的想要$phonenumbers{$selection} 而不是$phonenumbers{$name}

    # infinite loop version
    my $selection; 
    NUMBER:
    while ( 1 ) {
       print "Whose phone number do you want?\n";
       $selection = <STDIN>;
       chomp($selection);     # need to specify variable to chomp
    
       # if the name exists in the "database" print the phonenumber and exit the loop
       if ( exists $phonenumbers{$selection} ) {
          print "$selection: $phonenumbers{$selection}\n";
          last NUMBER;
       }
    
       # otherwise, the name is not in the database; print error message
       print "$selection is not in my database. Try another name.\n";
    }
    

    您也可以使用它的变体,它使用变量来保持循环移动:

    # boolean flag version
    my $selection; 
    my $valid_number = 0; # false
    
    while ( !$valid_number ) {
       print "Whose phone number do you want?\n";
       $selection = <STDIN>;
       chomp($selection);     # need to specify variable to chomp
    
       # if the name exists in the "database" print the phonenumber and exit the loop
       if ( exists $phonenumbers{$selection} ) {
          print "$selection: $phonenumbers{$selection}\n";
          $valid_number = 1; # true
       } 
       else {
          # otherwise, the name is not in the database; print error message
          print "$selection is not in my database. Try another name.\n";
       }
    }
    

    【讨论】:

      【解决方案3】:

      我已经用 cmets 重写了你的程序。希望对你有帮助。

      • 我认为my $numbers = reverse $name 是假的?

      • 总是use strictuse warnings每个 Perl 程序的顶部。它将为您节省大量调试和修复程序的时间

      • 无需使用如此冗长的标识符。它们一定是有意义的,但是当你第 40 次输入phonenumbers 时,你就会开始生气!

      • 记住chomp您的输入。除非您更改了记录分隔符或者您正在读取文件的最后一行,所有内容您使用 readline(更广为人知的 &lt;&gt;)读取的内容都会在末尾有一个换行符

      • 你错过了哈希的意义,当你得到它们时,这是一个令人愉快的啊!时刻。散列由它们的键索引,因此就像您可以使用$array[0] 访问数组的第一个元素一样,您可以使用$phonenumbers{Ian} 访问Ian 的电话号码。而已。无需遍历键即可找到所需的键

      • 您的while 循环需要更改测试,而您的不需要。您将$selection$phonenumbers{$name} 进行比较,如果它们不同,您将chomp $_(不带参数的chomp$_ 进行操作)并打印一条消息。两者都不会改变您正在比较的任何一个值,因此您的循环将永远循环......

      • ... 如果,也就是说,您的语法是正确的。 while 后面可以有 continue 块(但不用担心),但 else 无效,因此您的程序无法编译。

      这些要点主要解释了我对您的程序所做的更改,但这是其余的

      • fat comma 运算符=&gt; 很有用,因为它在视觉上将值成对联系在一起。作为一个列表,哈希只是key, value, key, value...,所以它在这种方式下很有用。但它在它之前的任何可能是标识符的东西周围加上隐式引号。这意味着我可以写,例如,gary =&gt; '0001' 而不是 'gary' =&gt; '0001'

      • 我已经使用$phones{lc $choice} 来访问哈希。 lc 运算符将其操作数作为一个全小写的字符串返回。这意味着$choice 可以是GarygaryGARY 甚至garY 来定位相同的哈希元素

      • 我没有一次又一次地询问一个不存在的电话号码,而是对其进行了更改,以便程序在没有这样的电话时调用die。修复它以做更多事情是一大步,因为您必须让用户以某种方式放弃并寻找更多名称。

      use strict;
      use warnings;
      
      my $name;
      my %phones = (
         gary  => '0001',
         ian   => '0002',
         nick  => '0003',
      );
      
      print "Whose phone number do you want: ";
      my $choice = <STDIN>;
      chomp $choice;
      
      my $number = $phones{lc $choice};
      die "$choice is not in my database. Try another name" unless defined $number;
      
      print "$choice: $number\n";
      

      【讨论】:

      • 谢谢。这有助于我看到更大的图景。
      猜你喜欢
      • 2012-09-10
      • 2016-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多