Perl 尝试从文件读取时未初始化的值$fh
我是perl新手。我编写了以下代码,以与输入相反的顺序读取文件,并将值打印到命令行Perl 尝试从文件读取时未初始化的值$fh,perl,Perl,我是perl新手。我编写了以下代码,以与输入相反的顺序读取文件,并将值打印到命令行 #! /usr/bin/perl use warnings; if(@ARGV == 0) { die "No file name given \n"; } my @argarr; while(@ARGV != 0) { my $tmp = pop @ARGV; push @argarr, $tmp; } foreach(@argarr) { #p
#! /usr/bin/perl
use warnings;
if(@ARGV == 0)
{
die "No file name given \n";
}
my @argarr;
while(@ARGV != 0)
{
my $tmp = pop @ARGV;
push @argarr, $tmp;
}
foreach(@argarr)
{
#print $_;
#print "\n";
if (! open my $fh , "< $_")
{
print "unable to open $_\n";
}
while(<$fh>)
{
chomp;
print "$_\n";
}
}
#/usr/bin/perl
使用警告;
如果(@ARGV==0)
{
die“没有给定文件名\n”;
}
我的@argar;
而(@ARGV!=0)
{
my$tmp=pop@ARGV;
推送@argarr,$tmp;
}
foreach(@argarr)
{
#打印美元;
#打印“\n”;
如果(!打开我的$fh,“<$\”)
{
打印“无法打开$\n”;
}
while()
{
咀嚼;
打印“$\u\n”;
}
}
然而,它并没有像预期的那样工作。它没有将文件打印到标准输出,而是显示以下错误:
Use of uninitialized value $fh in <HANDLE> at ./mtac.pl line 23.
readline() on unopened filehandle at ./mtac.pl line 23.
在at./mtac.pl第23行中使用未初始化值$fh。
在未打开的文件句柄上的readline()。/mtac.pl第23行。
请提供帮助。正如注释所说,您应该始终在脚本顶部使用
使用strict
。如果变量的作用域不正确,它将提示您
在你的剧本里
这将完成以下工作:
#!/usr/bin/perl
use strict;
use warnings;
if(@ARGV == 0)
{
die "No file name given \n";
}
my @argarr = reverse @ARGV;
foreach(@argarr)
{
my $fh;
unless(open $fh, '<', $_){
warn "unable to open file $_ : $! \n";
next;
}
while(<$fh>)
{
chomp;
print "$_\n";
}
close($fh);
}
#/usr/bin/perl
严格使用;
使用警告;
如果(@ARGV==0)
{
die“没有给定文件名\n”;
}
my@argarr=反向@ARGV;
foreach(@argarr)
{
我的$fh;
除非(打开$fh,
标量在词汇范围内,并且仅在if
分支内可见
if (! open my $fh , "< $_") { .. }
如果(!打开我的$fh,<$\uz”){..}
您可以通过以下方法解决此问题:
open my $fh , "<", $_ or print("$! $_"), next;
打开我的$fh,“这是因为$fh
的范围仅限于初始化它的块。下面是我将如何重写您的代码:
use strict;
use warnings;
use v5.10;
die "No file names given\n" unless @ARGV;
for my $file (reverse(@ARGV)) {
next unless -f $file;
open(my $fh, '<', $file) or die "Can't open file [$file]: $!\n";
while (<$fh>) {
chomp;
say;
}
close($fh);
}
使用严格;
使用警告;
使用v5.10;
除非@ARGV;
对于我的$file(反向(@ARGV)){
下一个除非-f$文件;
打开(my$fh,'在顶部添加一个使用strict;
,您将得到一个关于出错原因的非常清晰的提示。Calle逃避的错误消息,在添加strict
pragma后您将看到,它告诉您存在范围问题。$fh
在错误的范围内声明。好的,我得到了问题。我正在声明。)$fh位于if块内,因此它不可用于while循环。正确放置my$fh
的位置位于foreach
循环内。这也将关闭每个新文件名的句柄。您还可以使用@argarr
for(reverse@ARGV)摆脱@argarr
。您应该解释您认为在您的版本中修复的OP代码有什么问题。纯代码解决方案从来都不是很有用,因为它们会让人(其他人和OP都来这里寻求类似问题的帮助)除了复制粘贴您的代码之外,无法为自己做任何事情。在许多情况下,这不太可能作为插入代码来工作,而解释您修复了哪些问题以及代码如何工作的一些叙述几乎是不必要的
use strict;
use warnings;
use v5.10;
die "No file names given\n" unless @ARGV;
for my $file (reverse(@ARGV)) {
next unless -f $file;
open(my $fh, '<', $file) or die "Can't open file [$file]: $!\n";
while (<$fh>) {
chomp;
say;
}
close($fh);
}