在Perl中使用散列和数组

时间:2014-08-30 10:59:27

标签: arrays perl

下面我试图从文件中读取数据并尝试将它们存储在数组中。在这种情况下,数组大小应为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);

到那时我正在打印数组的值,但它什么都没打印。

3 个答案:

答案 0 :(得分:2)

必须始终use strictuse 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 strictuse 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语句不是必需的 - 换行符与正则表达式中的美元符号匹配。