2014-08-30 140 views
1

下面我試圖從文件中讀取數據並嘗試將它們存儲在數組中。在這種情況下數組的大小應該是6,因爲round的最大值是6(1,2,3,4,5,6)。在Perl中使用哈希和數組

我期待一個數組有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); 

在那麼結束我打印數組的值,但它沒有打印任何東西。

+4

始終'嚴格使用;使用警告;'在腳本開始時。 – Toto 2014-08-30 11:44:10

回答

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

它不是一個數組,你正在使用散列(%CHenergy)。要打印的按鍵:

my @the_keys = keys %CHenergy; 
print join(", ", @the_keys), "\n"; 

模塊Data::Dumper 5可以幫助您以顯示變量內容:

use Data::Dumper; 
#... 
print Dumper(%CHenergy), "\n"; 

注意:運用現代perl的方法來處理文件:

open (HND,"$outputFile"); 

應該是(在您的其他代碼中用HND替換$ HND):

open my $HND, ">", "$outputFile" or die $!; 
+0

這是給我這樣的輸出 $ VAR1 ='6'; $ VAR2 = 78956; $ VAR3 ='4'; $ VAR4 = 40271; $ VAR5 ='1'; $ VAR6 = 26731; $ VAR7 ='3'; $ VAR8 = 39792; $ VAR9 ='2'; $ VAR10 = 30111; $ VAR11 ='5'; $ VAR12 = 62232; 我如何格式化它。 1 some number 2 some number .. – 2014-08-30 11:09:47

+0

@MuhammadZaighum:use this:'print Dumper \%CHenergy;',注意反斜槓。 – Toto 2014-08-30 11:42:17

0

您應該use strictuse warnings。除了它的主要功能外,它還將幫助您瞭解Perl的一些原理和功能。如上所述,變量不是數組,而是散列。如果你想使用一個數組(這可能更適合這個問題),你必須在變量前加上符號(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說法是不necessarry - 換行是通過正則表達式的美元符號匹配。