我的代码有什么问题?我的DATA有4个块,但我的代码只打印前三个块的结果。从文件中读取数据得到的结果是一样的。
#!/usr/bin/perl
use 5.30.3;
use warnings;
my $sum=0;
my $block=1;
while(<DATA>){
chomp(my $line = $_);
if ($line !~ /^$/){
$sum = $sum+$line;
}else{
say "Sum of block-${block}: $sum";
$sum = 0;
$block++;
}
}
__DATA__
345
478
300
255
100
1200
1000
4000
182
347
611
714
打印结果:
Sum of block-1: 823
Sum of block-2: 655
Sum of block-3: 6200
程序在遇到空行但数据结束后没有额外行时打印总和。解决这个问题的一种方法是使用eof.
测试文件结束符。程序稍微重新排列
use strict;
use warnings;
use feature 'say';
my $sum = 0;
my $block = 0;
while (my $line = <DATA>) {
chomp $line;
if ($line =~ /^$/ or eof DATA){
++$block;
say "Sum of block-$block: $sum";
$sum = 0;
} else {
$sum += $line;
}
}
say "Read $block blocks";
__DATA___
...
当没有剩余数据时退出循环,并且在循环结束后不打印任何内容。
解决方案1:在循环
后打印一些内容while ( my $line = <DATA> ) {
chomp( $line );
if ( $line =~ /^$/ ) {
if ( defined( $sum ) ) {
say "Sum of block-${block}: $sum";
$sum = undef;
++$block;
}
next;
}
$sum += $line;
}
if ( defined( $sum ) ) {
say "Sum of block-${block}: $sum";
}
解决方案2:不要这么快退出循环。
while ( 1 ) {
my $line = <DATA>;
if ( !defined( $line ) || $line =~ /^$/ ) {
if ( defined( $sum ) ) {
say "Sum of block-${block}: $sum";
$sum = undef;
++$block;
}
if ( defined( $line ) ) {
next;
} else {
last;
}
}
chomp( $line );
$sum += $line;
}
只有当一行没有数据时(对输入数据没有任何验证),代码才会输出。
只有当输入数据的最后一行没有数据时,才会输出最后一个数据块的和。
学习下面的示例代码,这是对原始代码的轻微修改。
use strict;
use warnings;
use feature 'say';
my $sum=0;
my $block=1;
while( <DATA> ) {
chomp;
$sum += $1 if /(d+)/;
if( /^s*$/ && $sum ) {
say "Sum of block-${block}: $sum";
$sum = 0;
$block++;
}
}
say "Sum of block-${block}: $sum" if $sum;
exit 0;
__DATA__
345
478
300
255
100
1200
1000
4000
182
347
611
714
输出Sum of block-1: 823
Sum of block-2: 655
Sum of block-3: 6200
Sum of block-4: 1854
有一种更好的方法来对这类输入数据进行计算。
use strict;
use warnings;
use feature 'say';
my(@blocks,$count,%sum);
@blocks = do { local $/ = "nn"; <DATA> };
for my $block ( @blocks ) {
++$count;
$sum{$count} += $_ for $block =~ /(d+)/gsm;
}
say "Sum of block $_: $sum{$_}" for sort keys %sum;
exit 0;
__DATA__
345
478
300
255
100
1200
1000
4000
182
347
611
714
输出Sum of block 1: 823
Sum of block 2: 655
Sum of block 3: 6200
Sum of block 4: 1854