在我的代码中遇到perl无限循环问题

时间:2012-04-19 04:12:23

标签: perl

我正在尝试制作一个模拟杂货店故事情节线的程序。 如果输入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";
    }

    }

3 个答案:

答案 0 :(得分: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"; 
    } 

}

答案 1 :(得分:1)

“&lt;&gt;”函数返回一行输入,而不是字符。你需要在最后删除换行符。

答案 2 :(得分:1)

chomp是一个好主意,但有时候还不够。这是输入,因此有时您需要广泛接受模式。如其他两个帖子所示,您的模式太窄,它不允许输入结束时的行尾字符。

然而,之后是不是具有无关空间的角色,几乎相当于?所以也许你想这样做:

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

这意味着在换行符之前至少有一个非单词字符 - 如果有任何字符。

我在投入上广泛接受。这是我的一个应用程序中的日期输入字段中没有人会被激怒的原因。例如,我的日期字段不会尝试假装他们无法确定日期表达式,除非您包含前导0或遵循某些MM / DD模式。 (以及1到31之间的单个数字默认为当前月份或最近一个月或下个月,具体取决于日期逻辑(报告?计划?)和月份通过或离开的日期)。只是建议输入,这就是全部。