如何在 Perl 中解决此警告

Ale*_*exx 2 perl

我问这个类型的疑问句的前面,但没有提供完整的代码。

我正在阅读下面的文件并检查每列中存在的最大字宽,然后以正确对齐方式将其写入另一个文件。

id0 id1 id2 batch
0   34  56  70
2   3647    58  72  566
4   39  616 75  98  78 78987 9876 7899 776
89  40  62  76
8   42  64  78
34  455 544 565

Run Code Online (Sandbox Code Playgroud)

我的代码:

unlink "temp1.log";
use warnings;
use strict;
use feature 'say';
my $log1_file = "log1.log";
my $temp1 = "temp1.log";
open(IN1, "<$log1_file" ) or die "Could not open file $log1_file: $!";
my @col_lens;

while (my $line = <IN1>) {
    my @fs = split " ", $line;
    my @rows = @fs ;
    @col_lens =  map (length, @rows) if $.==1;
    for my $col_idx (0..$#rows) {
        my $col_len = length $rows[$col_idx];
        if ($col_lens[$col_idx] < $col_len) {
            $col_lens[$col_idx] = $col_len;
        }
    };
};
close IN1;
open(IN1, "<$log1_file" ) or die "Could not open file $log1_file: $!";
open(tempp1,"+>>$temp1") or die "Could not open file $temp1: $!";
while (my $line = <IN1>) {
    my @fs = split " ", $line;
    my @az;
    for my $h (0..$#fs) { 
        my $len = length $fs[$h]; 
        my $blk_len = $col_lens[$h]+1;
        my $right = $blk_len - $len;
        $az[$h] = (" ") . $fs[$h] . ( " " x $right );
    }
    say tempp1 (join "|",@az);
};
Run Code Online (Sandbox Code Playgroud)

我的警告

Use of uninitialized value in numeric lt (<) at new.pl line 25, <IN1> line 3.
Use of uninitialized value in numeric lt (<) at new.pl line 25, <IN1> line 4.
Use of uninitialized value in numeric lt (<) at new.pl line 25, <IN1> line 4.
Use of uninitialized value in numeric lt (<) at new.pl line 25, <IN1> line 4.
Use of uninitialized value in numeric lt (<) at new.pl line 25, <IN1> line 4.
Use of uninitialized value in numeric lt (<) at new.pl line 25, <IN1> line 4.
Run Code Online (Sandbox Code Playgroud)

我得到了正确的输出,但不知道如何删除此警告。

vin*_*k89 5

您会收到uninitialized警告,因为在检查$col_lens[$col_idx] < $col_len条件时,其中一个或两个都是undef.

解决方案1:

您可以通过使用next语句跳过检查此条件。

for my $col_idx (0..$#rows) {
        my $col_len = length $rows[$col_idx];
        
        next unless $col_lens[$col_idx];
        
        if ($col_lens[$col_idx] < $col_len) {
            $col_lens[$col_idx] = $col_len;
        }
    }
Run Code Online (Sandbox Code Playgroud)

解决方案 2:(不建议):
您可以Use of uninitialized value..通过将此行放在脚本顶部来简单地忽略警告。这将禁用uninitialized块中的警告。

no warnings 'uninitialized';
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅此链接


ike*_*ami 5

$col_idx最多可以是一行上的字段数减去一。对于第三行,这超过了 的最高索引@col_lens,最多包含 3 个元素。因此,执行以下操作毫无意义:

if ($col_lens[$col_idx] < $col_len) {
   $col_lens[$col_idx] = $col_len;
}
Run Code Online (Sandbox Code Playgroud)

将其替换为

if (!defined($col_lens[$col_idx]) || $col_lens[$col_idx] < $col_len) {
   $col_lens[$col_idx] = $col_len;
}
Run Code Online (Sandbox Code Playgroud)

有了这个,真的没有必要再检查$. == 1了。