为什么我的程序在一行输入后崩溃?

时间:2014-03-27 21:31:50

标签: regex perl loops multiline

我正在写一个简单的程序,它将句子中的每个单词都大写。它获得了多行输入。然后我遍历输入行,拆分行中的每个单词,将其大写,然后再次加入该行。如果输入是一个句子,这可以正常工作,但是一旦我输入两行我的程序崩溃(如果我等了太久,我的计算机会冻结。)

这是我的代码

@input = <STDIN>;
foreach(@input)
{   
        #reset @words
    @words= ();

    #readability
    $lines =$_;

    #split sentence
    @words = split( / /, $lines );
    #capitalize each word 
    foreach(@words){
            $words[$k] = ucfirst;
            $k++;
    }

    #join sentences again
    $lines = join(' ', @words);

    #create output line
    $output[$i]=$lines;
    $i++;
}

#print the result
print "\nResult:\n";
foreach(@output){
        print $output[$j],"\n";
        $j++;
}

有人可以告诉我它崩溃的原因吗?

2 个答案:

答案 0 :(得分:0)

  1. 使用严格(并告知未正确处理的变量,如指数)
  2. 用于var(数组)获取没有索引的可用项(Perl isn&#39; t Javascript)
  3. 什么不是错的(例如推送而不是索引)
  4. 在代码中:

    use strict; # always!
    
    my @input = <STDIN>; # the loop need in- and output
    my @output = ();
    
    for my $line (@input) # for makes readability *and* terseness easy
    {
        chomp $line; # get rid of eol
    
        #split sentence
        my @words = split( / /, $line );
    
        #capitalize each word
        for my $word (@words){  # no danger of mishandling indices
            $word = ucfirst($word);
        }
    
        #join sentences again
        $line = join(' ', @words);
    
        #create output line
        push @output, $line;
    }
    
    #print the result
    print "\nResult:\n";
    for my $line (@output){
        print $line, "\n";
    }
    

答案 1 :(得分:0)

问题在于您始终使用全局变量,因此它们在循环的迭代中保持其值。您已将@words重置为空列表,即使您不需要 - 在将split的结果分配给它时会被覆盖 - 但$k会无休止地增加。

$k最初设置为undef,其评估为零,因此对于第一句话,一切都很好。但是你将$k设置为@words中的元素数量,因此它从那里开始而不是从下一句话的零开始。你在@words上的循环变得无穷无尽,因为你正在分配(以及创建)$words[$k],因此数组的循环速度会越来越快。

同样的问题适用于$i$j,但执行永远不会重复使用。

Alshtough这是在Perl 4中工作的唯一方式,二十多年前,Perl 5使编程和调试的编程变得非常好。您现在可以使用my声明变量,您可以use strict(其中包括)坚持要使用您使用的每个变量,否则您的程序会赢得&#39;编译。还有use warnings也是非常宝贵的。在这种情况下,它会警告您使用未定义的变量$k等来索引数组。

如果我应用use strictuse warnings,请声明所有变量并将计数器初始化为零,然后我得到一个工作程序。它仍然不是很优雅,并且有更好的方法,但错误已经消失。

use strict;
use warnings;

my @input = <STDIN>;
my @output;
my $i = 0;

foreach (@input) {

  # readability
  my $lines = $_;

  # split sentence
  my @words = split ' ', $lines;

  # capitalize each word
  my $k = 0;
  foreach (@words) {
    $words[$k] = ucfirst;
    $k++;
  }

  # join sentences again
  $lines = join ' ', @words;

  #create output line
  $output[$i] = $lines;
  $i++;
}

print "\nResult:\n";
my $j = 0;
foreach (@output) {
  print $output[$j], "\n";
  $j++;
}