Regex 为什么我的程序在一行输入后崩溃?
我正在写一个简单的程序,将句子中的每个单词大写。它获得多行输入。然后我循环输入行,将行中的每个单词拆分,大写,然后再次连接行。如果输入的是一句话,这很好,但一旦我输入两行,我的程序就会崩溃(如果我等待太久,我的计算机就会冻结) 这是我的密码Regex 为什么我的程序在一行输入后崩溃?,regex,perl,loops,multiline,Regex,Perl,Loops,Multiline,我正在写一个简单的程序,将句子中的每个单词大写。它获得多行输入。然后我循环输入行,将行中的每个单词拆分,大写,然后再次连接行。如果输入的是一句话,这很好,但一旦我输入两行,我的程序就会崩溃(如果我等待太久,我的计算机就会冻结) 这是我的密码 @input = <STDIN>; foreach(@input) { #reset @words @words= (); #readability $lines =$_; #split
@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++;
}
@input=;
foreach(@input)
{
#重置@words
@单词=();
#可读性
$lines=$\ux;
#分句
@字=拆分(/,$行);
#每个单词大写
foreach(@words){
$words[$k]=ucfirst;
$k++;
}
#再次连接句子
$lines=join(“”,@words);
#创建输出行
$output[$i]=$line;
$i++;
}
#打印结果
打印“\n结果:\n”;
foreach(@output){
打印$output[$j],“\n”;
$j++;
}
有人能告诉我为什么它会崩溃吗
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";
}
使用strict;#总是
我的@input=;#循环需要输入和输出
我的@output=();
对于我的$line(@input)#for使可读性*和*简洁性变得容易
{
chomp$line;#摆脱eol
#分句
我的@words=split(/,$line);
#每个单词大写
对于我的$word(@words){#没有错误处理索引的危险
$word=ucfirst($word);
}
#再次连接句子
$line=join(“”,@words);
#创建输出行
按@输出,$line;
}
#打印结果
打印“\n结果:\n”;
对于我的$行(@output){
打印$line“\n”;
}
问题在于,您在整个过程中都在使用全局变量,因此它们在循环的迭代中保持其值。您已将@words
重置为空列表,即使您不需要-当您将拆分的结果分配给它时,它会被覆盖-但是$k
正在不断增加
$k
最初设置为undef
,其计算结果为零,因此对于第一句话,一切正常。但是您将$k
设置为@words
中的元素数,因此下一个句子从那里开始,而不是从零开始。您在@words
上的循环变得无穷无尽,因为您正在分配(并因此创建)$words[$k]
,因此数组的长度和循环速度一样快
同样的问题也适用于$i
和$j
,但执行永远不会达到重用它们的程度
尽管这是在Perl4中工作的唯一方法,但在20多年前,Perl5使编程更加易于编写和调试。您现在可以使用my
声明变量,也可以使用strict
,它(除其他外)坚持您使用的每个变量都必须声明,否则您的程序将无法编译。还有同样宝贵的使用警告。在这种情况下,它会警告您正在使用未定义的变量$k
等对数组进行索引
如果我应用use strict
和use 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++;
}
使用严格;
使用警告;
我的@input=;
我的@output;
我的$i=0;
foreach(@input){
#可读性
我的$行=$\;
#分句
我的@words=拆分“”,$line;
#每个单词大写
我的$k=0;
foreach(@words){
$words[$k]=ucfirst;
$k++;
}
#再次连接句子
$lines=连接“”,@words;
#创建输出行
$output[$i]=$line;
$i++;
}
打印“\n结果:\n”;
我的$j=0;
foreach(@output){
打印$output[$j],“\n”;
$j++;
}
想想,$k
从第二行开始的位置……但是说真的,通过my
声明所有变量并强迫自己通过使用strict
这样做要比使用诸如“reset@words”这样的废话好得多。使用s/(\W+/\u$1/g
可以简单得多。同上,谢谢,我是一个初学者,我很抱歉不知道严格和警告。我的代码现在可以用了,谢谢。我不被允许使用正则表达式,我必须先使用UCEX。真的吗?不允许使用正则表达式?在学生练习中,它们通常会让你使用新材料:)