如何从存储在文件中的表中获取特定索引

时间:2011-12-12 08:44:32

标签: perl perl-data-structures line-processing

我以表格形式从文件中获取输出。

这就是file.txt的样子。假设它是一个4 * 4矩阵

1 2 3 4
a b c d
e f g h
i j k l

现在我想获取表格的特定元素,说第二行和第三列。我使用下面的代码,但我没有得到ouput。

我将表存储在数组中并获取它的引用。

open(FH, "file.txt);
@Table = <FH>;
close FH;
$ref = \@Table;
print "${$ref[2][3]}";

输出应为“c”

请告诉我为什么输出不来了

3 个答案:

答案 0 :(得分:2)

你的意思是

print "$ref->[2][3]";

print "@$ref[2]->[3]";

根据您的描述,我假设您已声明@Table这样的内容:

my @Table = ([1, 2, 3, 4], 
     ['a', 'b', 'c', 'd'], 
     ['e', 'f', 'g', 'h'],
     ['i', 'j' 'k' 'l']);

也就是说,由于您没有使用my,我很确定您已离开use strict;。我怎么知道这个?如果你使用了Global symbol "@ref" requires explicit package name,你会收到一条消息说$ref[2]。您尝试使用@ref访问的内容是数组$ref中的元素;不是数组ref (中的元素。您也可能使用了parens()[)来封闭内部数组而不是括号(]my @Table = (1, 2, 3, 4, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' 'k' 'l'); ),这是一个问题,因为那会导致Perl将数组展平为

${$ref[2][3]}

这不是你想要的。

$ref->[2]->[3]存在多个问题。首先,访问数组ref中元素的正确方法是$ref->[2][3],也可以写成${"h"}(我通常会避免使用这种表示法,因为我认为它不太直观)。如果您成功获取该元素,那么您将会遇到Can't use string ("h") as a SCALAR ref,这是一个问题,因为Perl抱怨#!/usr/bin/perl use strict; use warnings; my $ref = []; open (my $fh, "<", "file.txt") or die "Unable to open file $!\n"; push @$ref, [split] for (<$fh>); close $fh; print $ref->[1]->[2],"\n"; # print value at second row, third column

编辑:由于问题在我的回答后发生了相当大的变化,因此以下是适用于该记录的解决方案:

use strict;use warnings;

我前几天在另一个答案中看到了Perl references quick-reference。看看它会让你受益匪浅。永远不要在没有{{1}}的情况下编写Perl代码。那是在惹麻烦。

答案 1 :(得分:2)

这是一个可以按您的方式运行的代码:

# ALWAYS use these 2 lines at the begining of your programs
use strict;
use warnings;

my $file = 'file.txt';
# use lexical file handler, 3 arg open and test if open is OK
open my $fh, '<', $file or die "unable to open '$file' for reading:$!";
my @Table;
while(<$fh>) {
    push @Table,[split];
}
close $fh;
my $ref = \@Table;
# this prints the third element of the second line
# array index start at 0
print $ref->[1][2];

<强>输出:

c

答案 2 :(得分:1)

不,不应该&#39; c&#39;。如果您想要 3rd 行(索引:0,1,2)和 4th 列(索引:0,1,2,3),则不是这样。

Perl是一种零索引语言,如C和Java以及任意数量的其他语言。如果您希望$table->[2][3]成为&#39; c&#39;,则需要以某种方式进行分配。

另外,简单地创建一个行数组将起作用。 @Table = <FH>;只创建一个包含四行的单维数组。你需要至少这个:

@Table = map { [ split ' ' ] } <FH>;

然而,这仍然无法解决索引问题。但这会:

@Table = ( undef, map { [ undef, split ' ' ] } <FH> );

建议设置$[ !!