2014-03-27 62 views
0

我正在写一个简单的程序,用大写的一个句子中的每个单词。它会得到一个多行输入。然后我循环输入行,分割行中的每个单词,将其大写,然后再次加入行。这工作正常,如果输入的是一个句子,但只要我输入两行我的程序崩溃(如果我等待太久我的电脑死机。)为什么我的程序在一行输入后崩溃?

这里是我的代码

@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++; 
} 

可能有人请告诉我它为什么崩溃?

+1

回想一下'$ k'在第二行开始......但严重的是,通过声明'my'所有的变量,并强迫自己这样做是通过'使用strict'将远比组装机一样好“复位@话”。 – amon

+1

使用s /(\ W +)/ \ u $ 1/g'可以简单得多。同上['为什么使用严格和警告?'](http://stackoverflow.com/questions/8023959/why-use-strict-and-warnings) – Miller

+0

谢谢,我是初学者,我很抱歉没有了解严格和警告。我的代码现在可用,谢谢。我不被允许使用正则表达式,我不得不使用ucfirst。 –

回答

0
  1. 使用严格的(和被告知处理不当喜欢你的指标变量)
  2. 使用了VAR(阵列)来得到一个可用的项目没有索引(Perl是不是JavaScript)的
  3. 什么ISN “T不能有错误(例如推,而不是指数)

在代码:

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"; 
} 
0

的问题是,使用的是克所有的lobal变量,所以他们在迭代循环中保持它们的值。您已将@words重置为空列表,即使您不需要 - 当您将split的结果指定给它时它将被覆盖 - 但$k正在不断增加。

$k最初设置为undef评估为零,因此第一句话一切都很好。但是,您将$k设置为@words中的元素数,因此它从那里开始,而不是从下一句的零开始。由于您正在分配(并因此创建)$words[$k],因此您的通过@words的循环变得无止境,因此数组的循环速度会随着循环而变得更快。

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

Alshtough这是在Perl 4中工作的唯一方式,在二十多年前,Perl 5已经使得编程在编写和调试方面变得非常好。你现在可以声明变量与my,你可以use strict哪些(除其他外)坚持,你使用的每个变量必须声明,否则你的程序将不会编译。也有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++; 
}