Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays Perl数组未保存所有变量_Arrays_Perl - Fatal编程技术网

Arrays 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

我有一个Perl程序,它解析来自外部程序的数据并将其保存到数组中。但是,有些数据没有保存,在以后尝试检索时返回为空

下面是解析数据的代码,它以
@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