为什么一次读取两行时会收到未初始化值警告?

Why am I getting an uninitialized value warning when reading two lines at a time?

我试图通过 while 循环一次读取两行,但出现此错误:

line    1
line    2
line    3
Use of uninitialized value in concatenation (.) or string at ....
Use of uninitialized value in concatenation (.) or string at ....
Use of uninitialized value in concatenation (.) or string at ....

脚本:

#!/usr/bin/perl 
use warnings;
use strict;

my $count = 1;
while ( my $two_lines = <DATA> . <DATA> ) {
    print $two_lines;
}


__DATA__
line    1
line    2
line    3

读取行运算符 <HANDLE> returns undef 从耗尽的文件句柄(在标量句柄中)读取时。因此,当您从 DATA 中读取(缺失的)第 4 行时,第一个警告出现在 while 循环的第二次迭代中。 接下来的两个警告来自第三次迭代,当您在耗尽的文件句柄上调用 <DATA> 两次时。

您可以使用不会是 undef 的表达式来解决此问题。由于您使用的是 perl >=v5.16,因此您可以使用

while (my $line = (<DATA> // '') . (<DATA> // '')) { ...

这并不是真正的错误,只是一个警告。您应该在偶数行号文件上收到 2 个警告,在奇数行号文件上收到 3 个警告。当它第一次通过 while 表达式时,它从第一次开始读取正常,然后当它第二次读取时,文件句柄为空,并打印警告。因为它第一次返回了一些东西,所以它会执行while循环的内容。最后一次,它将评估文件流两次,什么也没得到并中止循环,但两次警告它尝试连接空读取。如果你需要一个 while 循环,我会做

while ( my $first_lines = <DATA> ) {
    if (my $second_line = <DATA> ){
         print $first_lines . $second_line;
    }else{
        print $first_lines
        break;
    }
}

readline 又名 <$fh> returns undef 表示文件结束(或错误)。你不是在检查那个。修正:

while (1) {
   defined( my $line1 = <DATA> )
      or last;
   defined( my $line2 = <DATA> )
      or die("Premature end of file\n");

   print($line1 . $line2);
}

你可能不知道的是

while ( my $line = <DATA> ){ ... }

的缩写
while ( defined( my $line = <DATA> ) ){ ... }

这种转变只发生在像这样的简单结构上。

如果它不检查 definedness 然后它可以跳过最后一行,如果它只包含 0.
(保证其他行也有行分隔符,因此它们将继续正常工作。)


一种使其一次或两行类似地工作的方法是:

# take advantage of the built-in transformation
while ( my $two_lines = <DATA> ) {
  $two_lines .= <DATA> // '';

  ... # your code here
}