Perl hash + while循环

时间:2014-09-19 17:42:46

标签: perl hash while-loop

我是新来的,对编程很陌生。无论好坏,我决定使用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和直到相反,但没有运气。有人可以解释我缺少的东西吗?

3 个答案:

答案 0 :(得分:2)

如果输入符合您所需的条件,则使用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";
    }
}

答案 1 :(得分:1)

如果你想反复询问这个号码,你需要把它包含在你的循环中;否则$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";
   }
}

答案 2 :(得分:1)

我已经用评论重写了你的程序。我希望它有所帮助。

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

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

  • 无需使用如此冗长的标识符。它们必须是有意义的,但是你必须在第40次键入phonenumbers时开始烦恼!

  • 请记住chomp您的意见。除非您更改了记录分隔符或者正在阅读文件的最后一行,否则您使用readline读取的所有 - 更好地称为<> - 将在端

  • 你错过了哈希点,当你得到它们时,它是一个令人愉快的啊!时刻。哈希通过密钥进行索引,因此与使用$array[0]访问数组的第一个元素的方式相同,您可以使用{{1}访问Ian的电话号码}}。就是这样。没有必要循环键来找到你想要的那个

  • 您的$phonenumbers{Ian}循环需要进行测试,而您的while循环不需要。您将$selection$phonenumbers{$name}进行比较,如果它们不同,则chomp $_chomp没有参数会在$_上运行)并打印一条消息。既不会改变你要比较的值,也不会改变你的循环......

  • ...如果,那就是你的语法是正确的。 while之后可以continue阻止(但不要担心),但else无效,因此您的程序无法编译

这些要点主要解释了我对您的计划所做的更改,但其余部分

  • fat逗号运算符=>非常有用,因为它可以成对地将值绑定在一起。作为列表,哈希仅为key, value, key, value...,因此它以这种方式有用。但它在它之前的任何东西周围放置隐式引号,它可以是一个标识符。这意味着我可以编写gary => '0001'而不是'gary' => '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";