下面我试图从文件中读取数据并尝试将它们存储在数组中。在这种情况下,数组大小应为6,因为round的最高值为6(1,2,3,4,5,6)。
我期待一个包含6个元素的数组。我帮我错了。我是perl的新手。
if ( !defined($ARGV[0]) ) { print "ENTER OUTPUT Filename\n"; exit 1; }
$outputFile = $ARGV[0];
open(HND, "$outputFile");
while (<HND>)
{
chomp;
my $line = $_;
if ( /Node (.*) sending (.*) data to BS at time (.*) node 0 round (.*)$/ )
{
my $round = $4;
my $data = $2;
if ( exists($CHenergy{$round}) )
{
$CHenergy{$round} += $data;
}
else
{
$CHenergy{$round} = $data;
}
}
}
close HND;
print join(", ", $CHenergy);
到那时我正在打印数组的值,但它什么都没打印。
答案 0 :(得分:2)
您必须始终将use strict
和use warnings
添加到每个Perl程序的顶部,并使用my
声明所有变量。在这种情况下,它会告诉你没有哈希%CHenergy
。
请记住,Perl有三种主要数据类型 - 标量,以$
开头;数组,以@
开头;和哈希,以%
开头。并且他们可以共享标识符,例如,$data
,@data
和%data
可以同时存在并且彼此独立。使用方括号[...]
对哈希值进行索引,并使用大括号{...}
对数组值进行索引,但由于单个值为标量,因此它们都以$
开头;例如$data[0]
和$data{key}
。
您正在使用大括号 { .. }
来索引您认为是数组的内容,但$CHenergy{$round}
正在索引哈希 %CHenergy
。 @ARGV
是一个数组,您已使用方括号[ .. ]
成功编入索引。您需要以相同的方式访问数组@CHenergy
。
您还应该使用小写字母,数字和下划线来命名局部变量。大写字母保留用于全局标识符。
我修改了您的程序,以便更好地编写程序,并使用printf
格式化数据。
use strict;
use warnings;
my ($input_file) = @ARGV;
unless ( $input_file ) {
warn "Enter input filename\n";
exit 1;
}
open my ($hnd), '<', $input_file or die $!;
my @ch_energy;
while (<$hnd>) {
next unless /Node (.*) sending (.*) data to BS at time (.*) node 0 round (.*)/;
my ($data, $round) = ($2, $4);
$ch_energy[$round] += $data;
}
for my $i (0 .. $#ch_energy) {
my $energy = $ch_energy[$i];
printf "%2d => %d\n", $i, $energy if defined $energy;
}
答案 1 :(得分:1)
它不是一个数组,你使用的是哈希(%CHenergy
)。打印密钥:
my @the_keys = keys %CHenergy;
print join(", ", @the_keys), "\n";
模块Data::Dumper可以帮助您显示变量内容:
use Data::Dumper;
#...
print Dumper(%CHenergy), "\n";
注意:使用现代perl方法处理文件:
open (HND,"$outputFile");
应该是(在其余代码中用$ HND替换HND):
open my $HND, ">", "$outputFile" or die $!;
答案 2 :(得分:0)
您应该use strict
和use warnings
。除了它的主要功能外,它还将帮助您理解Perl的一些原理和功能。
正如所指出的,CHenergy
变量不是数组,而是散列。如果要使用数组(可能更适合此问题),则必须在变量前加上at符号(my @array
),并使用方括号而不是括号访问数组的成员($array[0]
)。
我就是这样做的:
#!/usr/bin/env perl
use strict;
use warnings;
my $filename = shift or die "You must supply an input file.";
open my $fh, $filename or die $!;
my @CHenergy = (0,0,0,0,0,0);
while (<$fh>) {
if ( /Node (.*) sending (.*) data to BS at time (.*) node 0 round (.*)$/ ) {
my $data = $2;
my $round = $4; # replace with "$4 - 1" when
# the round is from 1 to 6
# instead of 0 to 5
$CHenergy[$round] += $data;
}
}
close $fh;
print join(", ", @CHenergy);
作为对程序的以下编辑,我建议改变正则表达式(特别是第三对括号后的双空格)。如果您未使用字段$1
和$3
,请不要将它们包含在正则表达式中。您还可以对字段执行验证,以确保该行上有一个数字:
/^Node .* sending ([0-9]+) data to BS at time .* node 0 round ([0-5])$/
另请注意,chomp
语句不是必需的 - 换行符与正则表达式中的美元符号匹配。