如何在Perl中从二维数组打印行信息?

时间:2019-06-17 12:38:52

标签: perl multidimensional-array

我有以下二维数组(file.txt):

Code  Element  Repetitions
AL     Train       23
BM      Car        30
CN      Bike       44

我要从用户提供的输入(代码)中提取 相应的元素信息。

Example input: BM   
Example output:Car    

我尝试使用此代码,但不知道如何将输入名称与数组内容进行比较。非常感谢

#!/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);

1 个答案:

答案 0 :(得分:2)

这里有一些问题。通常可以通过在代码中添加use strict来找到它们。绝大多数有经验的Perl程序员将始终以以下方式启动程序:

use strict;
use warnings;

因为这些添加将发现程序员容易犯的大量常见错误。

找不到那样的第一个问题。这似乎是一个错字。您使用split /;+/分割了输入,但是输入文件似乎由空格分隔。因此,将split /;+/更改为split

现在,我们将use strict添加到您的代码中,看看会发生什么。

$ 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.

尽管此处列出了三个错误,但第二个和第三个错误都相同。但是,让我们从第一个开始。我程序中的第20行是:

foreach my $row ($content) {

但是$content变量是什么?您不会在其他任何地方使用它。我怀疑这是@content的错字。让我们进行更改,然后重试。

$ 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.

好的。这解决了第一个问题,但是我想我们现在必须看看重复的错误。这是由第21和22行生成的,如下所示:

    if ($content{$code}) {
        print "$content{$code}\n";

很显然,在这两行中都没有提到%content-那么问题是什么?

好吧,问题是在这两行中都提到了%content,但是在两种情况下都伪装成$content{$code}。您有一个名为@content的数组,并且您将使用$content[0]这样的语法在该数组中查找值。您使用{...}而不是[...]的面孔意味着您正在查看的是%content,而不是@content(在Perl中,您可以使用一个数组,散列-还有标量-都具有相同的名称,这总是一个糟糕的主意!)

但是我们不能仅仅将$content{$code}更改为$content[$code],因为$code是字符串(“ BM”)并且数组索引是整数。我需要从头开始思考,然后将数据实际存储在%content中,而不是@content中。而且,实际上,我认为这使代码更简单。

#!/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);

我们可以进行一些清理(例如,通过使用词法文件句柄和open()的三个参数版本)以获取此信息:

#!/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";
}