0

食料品店の列をシミュレートするプログラムを作成しようとしています。a を入力すると、ユーザーは名前を追加できます。c が入力された場合、人が回線を離れることをシミュレートします。p を入力すると、名前のリストが出力されます。q を入力すると終了します。

私のコードは無限ループになってしまい、その理由がわかりません。値を入力しようとするたびに、無効な入力を読み取って終了しません。他のものが機能しているかどうかはわかりませんが、それは私が助けを必要としているものではありません.

    $choice="";
    $name;
    @line=();
    print "\n";
    print "Choose an option:\n";
    print "a: Add person to end of line\n";
    print "c: Call the next person in line\n";
    print "p: Print the list of people in line\n";
    print "q: Quit\n";
    print "\n";

    while ($choice ne "q") {

    print "Your choice:";
    $choice = <>;
    print "\n";

    if($choice eq "a") {
            print "Enter name:";
            $name = <>;
            push(@line,$name);
    }
    elsif ($choice eq "c") {
    shift(@line);
    }
    elsif ($choice eq "p") {
            for ($i=0;$i<=scalar(@line);$i++) {
                    print (@line[$i]);
            }
    }
    elsif ($choice eq "q") {
            exit;
    }
    else {
            print "Invalid option";
    }

    }
4

3 に答える 3

4

@starkが正しく指摘しているように、ループの主な問題は、STDINから入力を取得した後に改行を削除していないことです。したがって、$choice は決してあなたの選択肢と一致せず、決してループから抜け出すことはありません。変更してみてください:

print "Your choice:";
$choice = <>;

print "Your choice:"; 
$choice = <STDIN>; 
chomp $choice;

chomp $choice文字列比較を行う前に、改行を削除する必要があることに注意してください。

また、「use warnings」と「use strict」を使用してスクリプトを作成してみてください。これにより、他の方法では気付かなかった多くの小さなエラーが検出されます。たとえば、スクリプトは次のようになります。

#!/usr/bin/env perl
use strict; 
use warnings; 

my $choice = ""; 
my $name; 
my @line = (); 
print "\n"; 
print "Choose an option:\n"; 
print "a: Add person to end of line\n"; 
print "c: Call the next person in line\n"; 
print "p: Print the list of people in line\n"; 
print "q: Quit\n"; 
print "\n"; 

while ( $choice ne "q" ) { 

    print "Your choice:"; 
    $choice = <STDIN>; 
    chomp $choice; 
    print "\n"; 

    if ( $choice eq "a" ) { 
        print "Enter name:"; 
        $name = <>; 
        push( @line, $name ); 
    } 
    elsif ( $choice eq "c" ) { 
        shift( @line ); 
    } 
    elsif ( $choice eq "p" ) { 
        for ( my $i = 0; $i <= scalar( @line ); $i++ ) { 
            print( $line[$i] ); 
        } 
    } 
    elsif ( $choice eq "q" ) { 
        exit; 
    } 
    else { 
        print "Invalid option"; 
    } 

}
于 2012-04-19T04:29:31.840 に答える
1

chomp良いアイデアですが、十分でない場合もあります。これはinputであるため、幅広い許容パターンが必要な場合があります。他の 2 つの投稿で示されているように、パターンが狭すぎるため、入力の最後に行末文字を入れることができません。

ただ、後ろに余計なスペースがある文字は、ほぼ同等ではないでしょうか。だからおそらくあなたはこれをしたい:

my $line = <>;
my ( $choice ) = $line =~ m/^\s*([acqp])\s*$/;

また、両方の文字を受け入れたい場合は、単純iに一致式 ( ) の最後にフラグを追加しm//、おそらくlc結果 (小文字)へのマップ コマンドを追加できます。

my $line = <>;
my ( $choice ) = map {; lc } $line =~ m/^\s*([acqp])\s*$/i;

また、太い指は気にしないと決めて、マッチ式を次のようにすることもできます。

m/^\s*([acqp])(?:\W.*)?$/i

これは、改行の前に少なくとも 1 つの非単語文字 (文字がある場合) を意味します。

私はインプットを広く受け入れることを実践しています。これが、私のアプリケーションの 1 つの日付入力フィールドで誰も憤慨しない理由です。私の日付フィールドは、たとえば、先頭に 0 を含めるか、MM/DD パターンに従わない限り、日付式を確認できないふりをしようとしません。(そして、1 から 31 までの 1 つの数値のデフォルトは、日付ロジック (レポート? 計画?) およびその月に過ぎた日または残った日付に応じて、現在の月、最新の月、または翌月になります)。入力に関するアドバイス、それだけです。

于 2012-04-19T05:50:46.190 に答える
1

「<>」関数は、文字ではなく入力行を返します。最後に改行を削除する必要があります。

于 2012-04-19T04:26:56.307 に答える