2014-09-19 122 views
2

我是新來的,編程很新。無論好壞,我決定使用Perl作爲打破編碼的一種方式。Perl散列+ while循環

我的問題涉及以下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 2014-09-19 17:56:38

+0

chomp選擇正確後,閱讀它,初學者 – ysth 2014-09-19 18:52:03

回答

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 strictuse warnings Perl程序的頂部。它將爲您節省大量時間調試和修復您的程序

  • 無需使用如此冗長的標識符。他們必須是有意義的,但是你必須在第四十次輸入phonenumbers時開始惱火!

  • 記住要輸入chomp。除非你已經改變了記錄分隔符,或者你正在閱讀從文件的最後一行,一切你閱讀使用readline - 更好地稱爲<> - 將有一個換行符在

  • 你缺少散列點結束,這是一個令人愉快的啊!你得到它們的時刻。哈希是,它們的密鑰索引,所以與訪問數組的第一個元素$array[0]相同,您可以使用$phonenumbers{Ian}訪問Ian的電話號碼。而已。沒有必要循環鍵找到你想要的那個

  • 你的while循環需要chnage測試,你的沒有。您將$selection$phonenumbers{$name}進行比較,如果它們不同,則chomp $_(沒有參數的chomp操作$_)並打印消息。既不改變你正在比較的任何值,所以你的循環將永遠循環...

  • ......如果你的語法是正確的。一個while可以有一個continue塊(但不用擔心),但else無效,所以你的程序不能編譯。

這些點主要是解釋我對你的程序進行的更改,但這裏的休息

  • 脂肪逗號操作=>是有用的,因爲它在視覺上的關係值一起成對。作爲一個列表,哈希僅僅是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"; 
+0

謝謝。這有助於我看到更大的圖景。 – Tad 2014-12-10 21:21:19