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