哈希错误,与数组索引等价

问题描述 投票:0回答:1

我想用数字键对哈希中的每个键重复一个过程。因此,有 3 种可能性,有 3 个 if,每一种都比较数组索引的值,因此,如果该位置

eq
为“sp”、“sp2”或“sp3”,它将在文档中搜索某个位置值,然后就可以打印了。它不起作用,每次只给我一个值,我想获取与哈希相对应的值。例如,哈希值可以是
%grupos=(1,'A',2,'G',3,'J')

文档.txt是:

HS0.32 
CS0,77
CD0.62
CT0,59 
C10,77
C20,62
C30,59
OS0.73
OD0,6
O10,73
O20,6 
NS0.75

代码是:

@ hibridaciones=("sp","sp2",sp3")
%grupos=(1,'A',2,'G',3,'J')
open (covalencia,"<", "cov.txt") or die "$!\n";
print keys %grupos;
keys %grupos; 
foreach my $z (keys %grupos) { 
    print "\n$z\n";
    if (@hibridaciones[my $z-1] eq "sp") {
        while (my $line = <covalencia>) {
            if ( $line=~/^C1/) {
                $line =~s/C1//;
                $radio=$line;
                print "\n$radio";
            }
        }
    }
    if (@hibridaciones[my $z-1] eq "sp2") {
        while (my $line = <covalencia>) {
            if ($line=~/^C2/) {
                $line =~s/C2//;
                $radio=$line;
                print "\n$radio";
            }
        }
    }
    if (@hibridaciones[my $z-1] eq "sp3") {
        while (my $line = <covalencia>) {
            if ($line=~/^C3/) {
                $line =~s/C3//;
                $radio=$line;
                print "\n$radio";
            }
        }
    }
}
close (covalencia);
perl
1个回答
0
投票

您的代码存在许多问题。您似乎不太可能实际运行此代码,因为它已损坏,缺少双引号会破坏代码的其余部分,加上缺少分号,这也会造成严重破坏。

但是你也有一些设计错误,或者糟糕的选择。我将在下面查看您的代码。

首先,始终使用

use strict; use warnings;
。这两个实用指令将防止您犯下难以发现的简单错误。一开始可能会很困难,但是没有它们的编码是非常危险的。

@ hibridaciones=("sp","sp2",sp3")
%grupos=(1,'A',2,'G',3,'J')

缺少两个分号。

@
和数组名称之间的空格很糟糕,但代码仍然有效。但你确实缺少一个双引号
sp3

open (covalencia,"<", "cov.txt") or die "$!\n";

以特定模式打开的三个参数很好。但这段代码仍然对裸字发出警告

covalencia
。更好的选择是使用词法变量,例如
open my $fh, "<", ...
。变量名
$fh
通常用作文件句柄。

keys %grupos; 

这个语句在 void 上下文中没有任何作用。

foreach my $z (keys %grupos) { 

你应该使用不言自明的变量名,这会给你省去很多麻烦。所以,你应该在这里使用

my $key

    if (@hibridaciones[my $z-1] eq "sp") {

这里有很多问题。

  • 首先,
    @
    用于数组切片。如果只有一个元素,则使用
    $
    。这将触发来自
    use warnings
    的警告。
  • my $z
    将创建一个名为
    $z
    的新变量。如果您启用了
    warnings
    ,它会警告您。
  • 这里的逻辑是错误的。您正在询问您自己声明的数组中的内容。这与代码无关,您可以用注释替换它:
    if ( $key == 1 ) {  # this is "sp"

请注意,这里的最后一点使整个

@hibridaciones
数组变得多余。


        while (my $line = <covalencia>) {

文件句柄只能使用一次到文件末尾。之后,

<covalencia>
将返回
undef
。这意味着以下
while
循环根本不会运行。您应该将文件中的行放入数组中,然后对其进行循环。例如。
for my $line (@lines)

            if ( $line=~/^C1/) {
                $line =~s/C1//;

虽然技术上没有错误,但在循环变量上使用

s///
会让您面临难以检测错误的风险。当使用
for/foreach
循环时,循环变量是原始变量的别名,因此更改循环变量将更改原始变量。在这种情况下不会发生这种情况,因为您正在读取文件,但由于我的建议是您使用其他解决方案,这将在稍后相关。

我的建议是捕获行尾,这是一个非破坏性的选项:

if ($line =~ /^C1(.*)/)
...然后
print $1
。或者使用
say
,它会自动添加换行符(请参阅下面的代码)。

                $radio=$line;
                print "\n$radio";

$radio
变量是多余的,可以删除。


总而言之,我最终得到的是这样的:

use strict;
use warnings;        # never code without strict and warnings enabled
use feature 'say';   # say $1 replaces print "$1\n"

my %grupos = (1,'A',2,'G',3,'J');
open (my $covalencia,"<", "cov.txt") or die "$!\n";
my @lines = <$covalencia>;    # your file is now in @lines
close ($covalencia);

foreach my $key (keys %grupos) {
    say "----- $key -----";
    if ($key == 1) {   # "sp"
        for my $line (@lines) {        # now we can loop as much as we want
            if ( $line=~ /^C1(.*)/) {  # capture to $1
                say $1;                # print $1
            }
        }
    } elsif ($key == 2) {   # "sp2"
        for my $line (@lines) {
            if ($line=~ /^C2(.*)/) {
                say $1;
            }
        }
    } elsif ($key == 3) {   # "sp3"
        for my $line (@lines) {
            if ($line=~ /^C3(.*)/) {
                say $1;
            }
        }
    }
}

给出输出:

----- 1 -----
0,77
----- 3 -----
0,59
----- 2 -----
0,62
© www.soinside.com 2019 - 2024. All rights reserved.