提问人:Alexx 提问时间:10/29/2020 最后编辑:Alexx 更新时间:10/29/2020 访问量:113
Perl:谁能告诉我如何解决此警告
Perl : Can anyone tell me how to resolve this warnings
问:
代码部分 1:
my $length = @array;
269 for (my $j=1; $j <= $length; $j+=1) {
270
271 if ( $fields[$j] =~ /dat/) {
}}
警告 1:
Use of uninitialized value within @array in pattern match (m//) at wrk.pl line 270
代码部分2:在这里,我正在尝试将十进制转换为十六进制
70 while (my $line = <DATA>) {
71 $line =~ s/ '([0-9]*)' / sprintf '0x%x', $1/eg;
72 print OUT $line;
}
警告 2:
Argument "" isn't numeric in sprint at wrk.pl line 71
更新
在我放置后,上面的两个警告现在都已解决,对于第二个警告,我更改了.for (my $j=1; $j <= $#array; $j+=1)
$line =~ s/ '([0-9]+)' / sprintf '0x%x', $1/eg;
我又收到两个警告
代码部分 3:在这里,我正在检查每列中存在的最大字宽
my @col_lns;
while (<file>) {
my @row = split " ",$_;
@col_lns = map ((length) @rows) if $. ==1;
for ( my $col_l =0; $col_l <$#row; $col_l+=1) {
my $col_ln = length $row[$col_l];
if ($col_lns[$col_l] < $coln) ###Here I am getting warning
{
$col_lns[$col_l] = $coln;
}
}
警告 3:
Use of uninitialized value in numeric lt (<)
代码部分 4;
my $pack1 = substr($add,4,4);
my $pack2 = substr($add,0,4);
警告 4
Use of $add in substr
substr outside of string
答:
我认为交换到是一个错别字。@array
@fields
在这里,您可以获得数组中的元素数:
my $length = @array;
因此,如果您的数组包含五个元素,现在将包含 5 个元素。数组中的五个元素的索引为 0 到 4。$length
现在,您可以遍历数组的元素:
for (my $j=1; $j <= $length; $j+=1) {
...
}
显然,我不知道你的数组中有什么,但你从索引 1 开始看起来很奇怪——通常,你会从索引 0 开始。您的代码一直持续到索引 5 - 但您的数组没有索引 5。正如我上面所说,您的索引从 0 到 4。
因此,您尝试访问索引 5 处的元素,没有这样的元素,并且在尝试使用该值时收到“未定义值”警告。
因此,您的代码可能如下所示:
# Start at 0; continue only while $j is less than $length
for (my $j=0; $j < $length; $j+=1) {
...
}
但是,这不是编写此代码的非常“Perlish”的方式。Perl 程序员很少使用这种“C 风格”循环语法。我们喜欢遍历一个值列表。
for my $j (0 .. $#array) {
..
}
这完全等同于您的原始代码,但(在我看来)它更容易阅读。
..
:这是“范围运算符”。它返回 0 和$#array
$#array
:每个数组都有一个与之关联的特殊变量 (),其中包含数组中最高的索引号。在本例中,这将是 4。$#arrayname
但我们可以改进这一点。你实际上并不想要数组索引,是吗?你真正想要的是数组元素。你可以直接得到这些。
for my $element (@array) {
if ($element =~ /dat/) {
..
}
}
最后,Perl 程序员可能会在这里用作变量,因为你通常不需要实际编写它:$_
for (@array) { # stores each element in turn in $_
if (/dat/) { # checks regex against $_
...
}
}
写下代码的分步演练。(感谢ikegami在评论中提到了其中的一些内容)
代码部分 1:
这部分的问题:
- 检查数组的长度,然后使用该长度遍历数组。
@array
@fields
- 从数组索引 1 开始,转到等于数组长度的数组索引(假设使用了正确的数组长度)。这是一次性错误。数组从 0 开始。您应该从 0 循环到数组的最大索引(小于长度 1)。
$#fields
- 警告 1 与代码中写入的内容不匹配。错误应该是关于数组的,这是您在代码中使用的。
@fields
- 警告 1 给出了错误的行号 270。 (最后两点表明您在复制错误消息后更改了代码,这是一件坏事)
- 警告 1 表示数组中的一个值未定义。由于循环条件中存在一次性错误,因此一个很好的猜测是未定义的值位于数组的末尾,并且一旦修复循环条件,此警告就会消失。
@array
代码第 2 部分:
- 您正在将空字符串提供给 ,它会警告您。由于您的匹配项被空格和单引号括起来,因此它很可能是输入中的空字符串(即 )。为避免匹配,您可以使用代替 ,即 。量词表示“匹配 1 次或多次”,而表示“匹配 0 次或多次”。请注意,这样做也会留下引号和空格,这些引号和空格在其他时间会被删除。
""
sprintf
''
+
*
[0-9]+
+
*
DATA
是文件内数据的保留文件句柄,使用文件底部的标记。除非这是您正在做的事情,否则您应该选择另一个文件句柄。最好是词汇,例如.__DATA__
my $fh
您进一步评论:
@ikegami,更改后仍会收到警告。
由于您没有提及这些警告是什么,因此我们无法为您提供帮助。
让我们尝试稍微更改一下 OP 的代码以制作可行的代码示例。
注#1:OP未提供输入数据样本
注意:#2:会更正确s/ '([0-9]+)' /sprintf ' 0x%x ', $1/eg;
use strict;
use warnings;
use feature 'say';
my @array = ( 'First sentence here', undef, 'Second dat sentence', undef, 'One more data sentence');
say '---- Part 1 ----';
for ( @array ) {
if( defined $_ and /dat/ ) {
say;
}
}
say '---- Part 2 ----';
while ( <DATA> ) {
s/ '([0-9]*)' /sprintf ' 0x%x ', $1/eg;
print $_;
}
__DATA__
some test data placed here for a test
ok, lets put some digits '3824' bits
some more '8902' bytes some text
number of files '0x834' you did not account for this
now finish with '123456' number
输出
---- Part 1 ----
Second dat sentence
One more data sentence
---- Part 2 ----
some test data placed here for a test
ok, lets put some digits 0xef0 bits
some more 0x22c6 bytes some text
number of files '0x834' you did not account for this
now finish with 0x1e240 number
评论
@array
@fields
for my $j (0..$#array)
[0-9]*
[0-9]+