我有一个简单的问题:
#! /usr/bin/perl
use warnings;
use strict;
my $protfile = "file.txt";
open (FH, $protfile);
while (<FH>) {
print (<FH>);
}
#! /usr/bin/perl
use warnings;
use strict;
my $protfile = "file.txt";
open (FH, $protfile);
while (my $file = <FH>) {
print ("$file");
}
答案 0 :(得分:5)
上下文。
您的第一个程序通过读取第一行来测试FH
上的文件结尾,然后在列表上下文中读取FH
作为print
的参数。这转换为整个文件,作为每个项目一行的列表。然后它再次测试EOF,很可能检测到它,然后停止。
你的第二个程序逐行迭代,每个程序在标量上下文中读取变量$file
,并单独打印它们。它通过while
语法中的特殊情况检测EOF。 (参见the documentation)
因此,在一个案例中,您的程序不打印第一行的具体原因是它在while
的参数中丢失了。请注意,这两个程序的结构非常不同:第一个只运行一次while
次迭代,而第二次只迭代一次。
PS:现在,管理文件的推荐方法倾向于词汇文件句柄(open my $file, 'name'; print <$file>;
)。
答案 1 :(得分:3)
因为你正在使用&lt;&gt;来消费第一行操作员然后在打印中再次使用它,所以第一行已经消失但你没有打印它。 &LT;&GT;是readline运算符。您需要打印$ _变量,或者像在第二个代码中那样将其分配给已定义的变量。你可以重写第一个:
打印;
它会起作用,因为如果你不给它任何东西,print会使用$ _。
答案 2 :(得分:2)
在标量上下文中使用时,<FH>
会返回文件中的下一行。
在列表上下文中使用时,<FH>
会返回文件中所有剩余行的列表。
while (my $file = <FH>)
是一个标量上下文,因为你正在分配一个标量。 while (<FH>)
是while(defined($_ = <FH>))
的缩写,因此它也是标量上下文。 print (<FH>);
使它成为一个列表上下文,因为你将它用作可以接受多个参数的函数的参数。
while (<FH>) {
print (<FH>);
}
while
部分将第一行读入$_
(永不再使用)。然后print
部分一次读取所有行,然后再将它们全部打印出来。然后再次检查while
条件,但由于现在没有行,<FH>
返回undef
并且循环在一次迭代后退出。
while (my $file = <FH>) {
print ("$file");
}
做了你可能期望的更多:读取然后在循环的每次迭代中打印一行。
顺便说一下,print $file;
与print ("$file");
答案 3 :(得分:1)
while (<FH>) {
print (<FH>);
}
改为使用:
while (<FH>) {
print $_;
}