Arrays Perl数组未保存所有变量
我有一个Perl程序,它解析来自外部程序的数据并将其保存到数组中。但是,有些数据没有保存,在以后尝试检索时返回为空 下面是解析数据的代码,它以Arrays Perl数组未保存所有变量,arrays,perl,Arrays,Perl,我有一个Perl程序,它解析来自外部程序的数据并将其保存到数组中。但是,有些数据没有保存,在以后尝试检索时返回为空 下面是解析数据的代码,它以@packetData的形式出现: if(@packetData[0] ne ""){ if(!$detectedClient{"@packetData[0]"}) { my $rawSignal = average(@packetData[2]); my $distance = 10**((27.55-(20*l
@packetData
的形式出现:
if(@packetData[0] ne ""){
if(!$detectedClient{"@packetData[0]"}) {
my $rawSignal = average(@packetData[2]);
my $distance = 10**((27.55-(20*logten(2437))+abs($rawSignal))/20);
my @newClient = ($rawSignal, # Signal (dBm)
1, # Count
@packetData[0], # Source MAC
time(), # Last seen
$distance); # Distance (m)
$detectedClient{"@packetData[0]"} = [@newClient];
$uniqueClient++;
print "++ New probe request from @packetData[0] [$rawSignal dBm, $distance m]\n";
} else {
$detectedClient{"@packetData[0]"}[1]++;
$detectedClient{"@packetData[0]"}[3] = time();
}
}
print
语句可以很好地显示信号和距离,但是尝试从detectedClient
数组中显示它时,下面的代码会给出一个空格:
for $key2 ( keys %detectedClient) {
#Signal, Count, MAC, Time
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($detectedClient{$key2}[3]);
my $lastSeen = sprintf("%04d/%02d/%02d %02d:%02d:%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec);
print STDOUT sprintf("!! %-20s %10s %-20s\n", $detectedClient{$key2}[2], $detectedClient{$key2}[1], $lastSeen, $detectedClient{$key2}[0], $detectedClient{$key2}[4]);
}
知道为什么会发生这种情况吗?整个数组的语法是
@array
,但要访问单个元素,它是(例如$array[0]
此外,还有一种更好的方法可以在上下文中编写内部if
第三,您正在为detectedClient
使用数组引用,因此可以将语法从$detectedClient{$smac}[1]+
更改为$detectedClient{$smac}->[1]+
,这样可以更清楚地了解意图。我在下面的代码中更改了它,您也可以在打印时更改它
下面是修改后的代码,以反映所有这些,并将其缩短为使用标量:
my $smac = $packetData[0];
if ($smac ne "") {
if(! ref($detectedClient{$smac})) {
my $rawSignal = average($packetData[2]);
my $distance = 10**((27.55-(20*logten(2437))+abs($rawSignal))/20);
my @newClient = ($rawSignal, # Signal (dBm)
1, # Count
$smac, # Source MAC
time(), # Last seen
$distance); # Distance (m)
$detectedClient{$smac} = [@newClient];
$uniqueClient++;
print "++ New probe request from $smac [$rawSignal dBm, $distance m]\n";
} else {
my $ptr = $detectedClient{$smac};
$ptr->[1]++;
$ptr->[3] = time();
}
}
更新: 应用标量和一点reindent,打印代码如下所示:
for $key2 ( keys %detectedClient) {
my $ptr = $detectedClient{$key2};
#Signal, Count, MAC, Time
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
localtime($ptr->[3]);
my $lastSeen = sprintf("%04d/%02d/%02d %02d:%02d:%02d",
$year+1900, $mon+1, $mday, $hour, $min, $sec);
print STDOUT sprintf("!! %-20s %10s %-20s\n",
$ptr->[2], $ptr->[1],
$lastSeen, $ptr->[0], $ptr->[4]);
}
现在,更容易看出[对我来说,至少;-)]格式短于两个字段[所以最后两个参数不会被打印出来]
所以,换成这样:
printf("!! %-20s %10s %-20s %10s %10s\n",
没有打印信号和距离,因为您的图案(
“!!%-20s%10s%-20s\n”
)没有引用它们(第四和第五个值)。修正:
使用以下内容进行测试:(必须将$key2的
更改为我的$key2的)
输出:
Scalar value @packetData[0] better written as $packetData[0] at a.pl line 18.
Scalar value @packetData[0] better written as $packetData[0] at a.pl line 19.
Scalar value @packetData[2] better written as $packetData[2] at a.pl line 20.
Scalar value @packetData[0] better written as $packetData[0] at a.pl line 24.
Scalar value @packetData[0] better written as $packetData[0] at a.pl line 27.
Scalar value @packetData[0] better written as $packetData[0] at a.pl line 29.
Scalar value @packetData[0] better written as $packetData[0] at a.pl line 31.
Scalar value @packetData[0] better written as $packetData[0] at a.pl line 32.
++ New probe request from foo [4.5 dBm, 0.0164302613184467 m]
!! foo 1 2016/05/16 15:19:38 4.5 0.0164302613184467
下次,请提供一个最小的、可运行的问题演示。始终使用use strict;使用警告qw(全部)代码>!我在脚本的顶部都有这两个选项,但是为了便于理解,我省略了它们(连同脚本的其余部分)clarity@CyberJacob:如果您有使用警告
,那么您将忽略消息Scalar value@packetData[0],最好写为$packetData[0]
。你为什么要这样做?@CyberJacob因为当你必须通过猜测来填充缺失的部分时,很难调试其他人的代码,我建议创建一个包含示例输入数据的脚本。关于“我在脚本顶部有两个”,嗯,你发布的代码没有用它们编译,并且会发出许多警告。$foo{bar][1]
与$foo{bar}->[1]完全相同
。括号/大括号之间的箭头不是必需的。请阅读:除了代码之外,您的答案需要更改。您声称OP由于省略了下标之间的箭头而犯了语法错误。他没有。这不是任何类型的错误。不回答问题。(另外,添加箭头与习惯用法相反,$ptr
是一个不必要的模糊变量名。否定if
允许使用if(my$client=$detectedClient{$smac}){…前else部分…}后else{…前然后部分…}
@Craig Estey,是的,我是认真的。尽管有很多方法可以做事情,但人们确实发现某些方法比其他方法更清晰。我不知道为什么你会觉得很难相信???//你可以自由地编写与大多数其他方法不同的代码,但不要假装这样更容易阅读。缺乏一致性是最大的缺点o可读性和可维护性。//哇,你不仅使用了一个毫无意义的变量名,还试图让别人认为Perl有指针!教得好!//不,你是坚持使用各种无用符号的人。你列出了OP“做错”的三件事,这其实一点也不错。其中一个只是丑陋和制造警告,但根本不会影响结果。第二个只是文体上的选择。第三个是你错误地告诉他他做错了他没有做错的事情,而你的方式更加丑陋和不必要。直到@ikegami将他的答案发布到co由于询问者的代码实际上有什么问题,所以您修改了答案,将该信息也包括在内。
use strict;
use warnings qw( all );
use List::Util qw( sum );
sub average { sum(@{ $_[0] })/@{ $_[0] } }
sub logten { log($_[0])/log(10) }
my @packetData = ("foo", undef, [ 4, 5 ]);
my %detectedClient;
my $uniqueClient;
if(@packetData[0] ne ""){
if(!$detectedClient{"@packetData[0]"}) {
my $rawSignal = average(@packetData[2]);
my $distance = 10**((27.55-(20*logten(2437))+abs($rawSignal))/20);
my @newClient = ($rawSignal, # Signal (dBm)
1, # Count
@packetData[0], # Source MAC
time(), # Last seen
$distance); # Distance (m)
$detectedClient{"@packetData[0]"} = [@newClient];
$uniqueClient++;
print "++ New probe request from @packetData[0] [$rawSignal dBm, $distance m]\n";
} else {
$detectedClient{"@packetData[0]"}[1]++;
$detectedClient{"@packetData[0]"}[3] = time();
}
}
for my $key2 ( keys %detectedClient) {
#Signal, Count, MAC, Time
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($detectedClient{$key2}[3]);
my $lastSeen = sprintf("%04d/%02d/%02d %02d:%02d:%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec);
printf("!! %-20s %5s %-20s %20s %20s\n",
$detectedClient{$key2}[2],
$detectedClient{$key2}[1],
$lastSeen, $detectedClient{$key2}[0],
$detectedClient{$key2}[4],
);
}
Scalar value @packetData[0] better written as $packetData[0] at a.pl line 18.
Scalar value @packetData[0] better written as $packetData[0] at a.pl line 19.
Scalar value @packetData[2] better written as $packetData[2] at a.pl line 20.
Scalar value @packetData[0] better written as $packetData[0] at a.pl line 24.
Scalar value @packetData[0] better written as $packetData[0] at a.pl line 27.
Scalar value @packetData[0] better written as $packetData[0] at a.pl line 29.
Scalar value @packetData[0] better written as $packetData[0] at a.pl line 31.
Scalar value @packetData[0] better written as $packetData[0] at a.pl line 32.
++ New probe request from foo [4.5 dBm, 0.0164302613184467 m]
!! foo 1 2016/05/16 15:19:38 4.5 0.0164302613184467