Reputation: 83
I have the following two dimensional array (file.txt):
Code Element Repetitions
AL Train 23
BM Car 30
CN Bike 44
From an input (Code) given by the user, I want to extract the corresponding Element information.
Example input: BM
Example output:Car
I tried with this code but I do not know how to compare the input name with array content. Thank you a lot
#!/usr/bin/perl
use strict;
use warnings;
print("Type code: ");
my $code = <STDIN>;
chomp($code);
my @content;
if(!open(TABLET, "file.txt")){
die "Unable to open the file\n";
}
while(<TABLET>){
chomp;
push @content, [split / /];
}
foreach my $row ($content) {
if ($content{$code}) {
print "$content{$code}\n";
}
}
close(TABLET);
Upvotes: 0
Views: 91
Reputation: 69314
There are a few problems here. And they can mostly be found by adding use strict
to your code. The vast majority of experienced Perl programmers will always start their programs with:
use strict;
use warnings;
as these additions will find a huge number of common mistakes that programmers are prone to make.
The first problem can't be found like that. It seems to be a typo. You split your input using split /;+/
but your input file seems to be delimited by whitespace. So change split /;+/
to just split
.
Now let's add use strict
to your code and see what happens.
$ perl 2d
Global symbol "$content" requires explicit package name (did you forget to declare "my $content"?) at 2d line 20.
Global symbol "%content" requires explicit package name (did you forget to declare "my %content"?) at 2d line 21.
Global symbol "%content" requires explicit package name (did you forget to declare "my %content"?) at 2d line 22.
Execution of 2d aborted due to compilation errors.
Although there are three errors listed here, the second and third ones are both the same. But let's start with the first. Line 20 in my program is:
foreach my $row ($content) {
But what's that $content
variable? You don't use that anywhere else. I suspect it's a typo for @content
. Let's change that and try again.
$ perl 2d
Global symbol "%content" requires explicit package name (did you forget to declare "my %content"?) at 2d line 21.
Global symbol "%content" requires explicit package name (did you forget to declare "my %content"?) at 2d line 22.
Execution of 2d aborted due to compilation errors.
Ok. That fixed the first problem, but I guess we now have to look at the repeated error. This is generated by lines 21 and 22, which look like this:
if ($content{$code}) {
print "$content{$code}\n";
Obviously, there's no mention of %content
on either of those lines - so what's the problem?
Well, the problem is that %content
is mentioned on both of those lines, but it's disguised as $content{$code}
in both cases. You have an array called @content
and you'd look up values in that array using syntax like $content[0]
. The face that you're using {...}
instead of [...]
means that you're looking in %content
, not @content
(in Perl you're allowed to have an array and a hash - and also a scalar - all with the same name, which is always a terrible idea!)
But we can't just change $content{$code}
to $content[$code]
because $code
is string ("BM") and array indexes are integers. I we need to rethink this from scratch and actually store the data in %content
, not @content
. And, actually, I think that makes the code simpler.
#!/usr/bin/perl -w
use strict;
use warnings;
print("Type code: ");
my $code = <STDIN>;
chomp($code);
my %content;
if (!open(TABLET, "file.txt")){
die "Unable to open the file\n";
}
while(<TABLET>){
chomp;
my @record = split;
$content{$record[0]} = \@record;
}
if (exists $content{$code}) {
print "$content{$code}[1]\n";
} else {
print "$code is not a valid code\n";
}
close(TABLET);
We can clean that up a bit (for example, by using lexical filehandles and the three-arg version of open()
) to get this:
#!/usr/bin/perl
use strict;
use warnings;
print("Type code: ");
chomp( my $code = <STDIN> );
my %content;
open my $tablet_fh, '<', 'file.txt'
or die "Unable to open the file\n";
while(<$tablet_fh>){
chomp;
my @record = split;
$content{$record[0]} = \@record;
}
if (exists $content{$code}) {
print "$content{$code}[1]\n";
} else {
print "$code is not a valid code\n";
}
Upvotes: 2