anurag86
anurag86

Reputation: 1687

hash doesnt print right while reading from file in perl

I am trying to build a hash in perl by reading a file. File content is as below:

s1=i1
s2=i2
s3=i3

And my code is as below:

my $FD;
open ($FD, "read") || die "Cant open the file: $!";
while(<$FD>){
    chomp $_;
    print "\n Line read = $_\n";
    $_ =~ /([0-9a-z]*)=([0-9a-zA-Z]*)/;
    @temp_arr=($2,$3,$4);
    print "Array = @temp_arr\n";
    $HASH{$1}=\@temp_arr;
    print "Hash now = ";
    foreach(keys %HASH){print "$_ = $HASH{$_}->[0]\n";};


}

And my output as below

 Line read = s1=i1
Array = i1
Hash now = s1 = i1

 Line read = s2=i2
Array = i2
Hash now = s2 = i2
s1 = i2

 Line read = s3=i3
Array = i3
Hash now = s2 = i3
s1 = i3
s3 = i3

Why is the value for all the keys in the end printed as i3?????

Upvotes: 0

Views: 86

Answers (5)

Andrey
Andrey

Reputation: 1818

Try this.

open (my $FD, "read") || die "Cant open the file: $!";
my %HASH = map {chomp $_; my @x = split /=/, $_; $x[0] => $x[1]} <$FD>;
print "Key: $_ Value: $HASH{$_}\n" for (sort keys %HASH);

Upvotes: 0

asjo
asjo

Reputation: 3194

Because you are putting references to the same array in each value.

Try something like this:

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

my %result;

open my $fh, '<', 'read' or die $!;
while (my $line=<$fh>) {
    chomp $line;
    my ($key, $value)=split /=/, $line, 2;
    die "$key already exists" if (exists $result{$key});
    $result{$key}=$value;
}

print Dumper(\%result);

Output is:

$VAR1 = {
          's1' => 'i1',
          's3' => 'i3',
          's2' => 'i2'
        };

Upvotes: 3

Chris B.
Chris B.

Reputation: 49

Beside the errors in your "open" statement, try keeping it simple then make it unreadable.

my ($FD, $a, $b, $k);
$FD = "D:\\Perl\\test.txt";
open (FD, "<$FD") or die "Cant open the file $FD: $!";
while(<FD>){
    chomp $_;
    print "\n Line read = $_\n";
    ($a, $b) = split('=', $_);
    print "A: $a, B: $b\n";
    $HASH{$a}="$b";
    print "Hash now ..\n";
    foreach $k (sort keys %HASH){
        print "Key: $k -- HASH{$k} = $HASH{$k}\n";
    }
}

Upvotes: -1

Alcanzar
Alcanzar

Reputation: 17155

\@temp_arr is a reference to the global variable @temp_arr. You are re-initializing it repeatedly, but it's still a reference to the original variable.

You need to lexically scope the @temp_arr (my @temp_arr=($2,$3,$4);) or pass a new reference in to the hash ($HASH{$1} = [ $2,$3,$4 ];)

Upvotes: 2

anurag
anurag

Reputation: 202

Try this:

my $FD;
open ($FD, "read") || die "Cant open the file: $!";
for(<$FD>){
   chomp $_;
   push(@temp_arr,$1,$2) if($_=~/(.*?)=(.*)/);
}
%HASH=@temp_arr;
print Dumper \%HASH;

Upvotes: 1

Related Questions