Как вывести информацию о строках из двумерного массива в Perl? - PullRequest
0 голосов
/ 17 июня 2019

У меня есть следующий двумерный массив (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 Ответ

2 голосов
/ 17 июня 2019

Здесь есть несколько проблем.И их в основном можно найти, добавив 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";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...