2014-09-19 16 views
2

Я новичок здесь и довольно новичок в программировании. К лучшему или худшему я решил использовать Perl как способ проникнуть в кодирование.Perl hash + while loop

Мой вопрос касается следующего 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}"; 
} 

Я хочу, чтобы оставаться в курсе и попросить правильное имя, если неправильное имя дано. В противном случае я хочу, чтобы он отображал правильный номер телефона. Прямо сейчас он остается в цикле, несмотря ни на что.

Я пробовал использовать, если и до этого, но не повезло. Может кто-нибудь объяснить, что я пропущу?

+0

Вы только проверка '' один раз - вам необходимо запросить его снова. – Sobrique

+0

Выбор chomp сразу после прочтения, для стартеров – ysth

ответ

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

Создать бесконечный цикл и разразится используя 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

Я переписал вашу программу с комментариями. Я надеюсь, что это помогает.

  • Предполагаю, что my $numbers = reverse $name является поддельным?

  • Всегдаuse strict и use warnings в верхней части каждый программы Perl. Это сэкономит вам неисчислимое время отладки и исправления вашей программы

  • Не нужно использовать такие длинные идентификаторы. Они должны быть значимыми, но вы начнете раздражаться в сороковой раз, когда вам нужно ввести phonenumbers!

  • запомнить chomp Ваши данные. Если вы не изменили разделитель или вы читаете последнюю строку из файла, всех вы читать с помощью readline - более известного как <> - будет иметь символ новой строки в конце

  • Вы недостающая точку хэш , и это восхитительно А! момент, когда вы их получите. Хэши индексируются по их ключу, поэтому так же, как вы можете получить доступ к первому элементу массива с помощью $array[0], вы можете получить доступ к номеру Ian с помощью $phonenumbers{Ian}. Вот и все. Вам не нужно зацикливаться на клавишах, чтобы найти тот, который вы хотите

  • Ваш цикл while должен пройти тест, а ваш нет. Вы сравниваете $selection с $phonenumbers{$name}, и если они отличаются от вас, то chomp $_ (a chomp без параметра действует на $_) и распечатайте сообщение.Не изменяйте ни одно из значений, которые вы сравниваете, поэтому ваш цикл будет цикл навсегда ...

  • ... если, то есть, ваш синтаксис был верным. A while может иметь блок continue после него (но не беспокойтесь об этом), но else недействителен, поэтому ваша программа не компилируется.

Эти моменты в основном объяснить изменения, которые я сделал в своей программе, но вот остальные

  • жира запятая оператор => является полезным, поскольку он визуально стяжек значения в парах. Как список, хеш - это всего лишь key, value, key, value..., поэтому он так полезен. Но это также ставит неявные кавычки вокруг чего-либо перед ним, что может быть идентификатором. Это означает, что я могу написать, например, gary => '0001' вместо 'gary' => '0001'

  • Я использовал $phones{lc $choice}, чтобы получить доступ к хэш. Оператор lc возвращает свой операнд как строку во всех строчных. Это означает, что $choice может быть Gary или gary или GARY или даже 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"; 
+0

Спасибо. Это помогает мне увидеть большую картину. – Tad