Need help reading two-dimentional array from a file

D

DanchikPU

Hi,

I am attempting to read in two-dimentional array from a file, but my
data is being treated as a flat array.

The data file looks something like this:

(['abcd','qwerty','L','1234'],
['abce','qwerty','L','1234'],
['abcf','qwerty','L','1234'],
['abcg','qwerty','L','1234']);

In the code, I am doing to standart

open(DATA, "foo.txt")
@foo=<DATA>
close(DATA);

Accessor $foo[0] will return the first line, but $foo[0][0] fails

The data is formatted perfectly, I have tried pasting it directly into
the code and everything works, it's only when I try to read it in that
I fail.

Thanks in advance for your help!

~d
 
P

Paul Lalli

I am attempting to read in two-dimentional array from a file,
but my data is being treated as a flat array.

The data file looks something like this:

(['abcd','qwerty','L','1234'],
['abce','qwerty','L','1234'],
['abcf','qwerty','L','1234'],
['abcg','qwerty','L','1234']);

In the code, I am doing to standart

open(DATA, "foo.txt")
@foo=<DATA>
close(DATA);

Accessor $foo[0] will return the first line, but $foo[0][0]
fails

The data is formatted perfectly, I have tried pasting it
directly into the code and everything works, it's only when I
try to read it in that I fail.

'[' and ']' and ',' mean absolutely nothing special in text. They
only mean anything in code. Perl has no way of knowing that you
wanted the text you read from the file to act as though it was
actually typed into your program.

There are many solutions I can think of off the top of my head:
1) Parse the file looking for your data files and build your 2-
dimensional array.
2) Use eval() to treat the text as Perl code
3) Change how you're creating the file to begin with.

Here's a few examples of each solution:
1)
#!/usr/bin/perl
use strict;
use warnings;
my @foo;
while (<DATA>){
my @values = /'(.*?)'/g;
push @foo, \@values;
}

2)
#!/usr/bin/perl
use strict;
use warnings;
my @foo = eval do { local $/; <DATA>} ;

3)
Program that creates the file:
#!/usr/bin/perl
use strict;
use warnings;
use Storable;
my @foo;
#populate @foo
store(\@foo, 'foo.txt');
__END__

Program that reads the file:
#!/usr/bin/perl
use strict;
use warnings;
use Storable;
my @foo = @{ retrieve('foo.txt') };


Please take EXTREME CAUTION with method #2. If you're not 100% sure
you know exactly what the contents of that file are, you're opening
yourself up to a massive security hole. That method will execute ANY
perl code found in the file. Including code that might contain, for
example:
system("rm -rf /");

Paul Lalli
 
D

DanchikPU

I am attempting to read in two-dimentional array from a file,
but my data is being treated as a flat array.
The data file looks something like this:
(['abcd','qwerty','L','1234'],
['abce','qwerty','L','1234'],
['abcf','qwerty','L','1234'],
['abcg','qwerty','L','1234']);

In the code, I am doing to standart
open(DATA, "foo.txt")
@foo=<DATA>
close(DATA);
Accessor $foo[0] will return the first line, but $foo[0][0]
fails
The data is formatted perfectly, I have tried pasting it
directly into the code and everything works, it's only when I
try to read it in that I fail.

'[' and ']' and ',' mean absolutely nothing special in text. They
only mean anything in code. Perl has no way of knowing that you
wanted the text you read from the file to act as though it was
actually typed into your program.

There are many solutions I can think of off the top of my head:
1) Parse the file looking for your data files and build your 2-
dimensional array.
2) Use eval() to treat the text as Perl code
3) Change how you're creating the file to begin with.

Here's a few examples of each solution:
1)
#!/usr/bin/perl
use strict;
use warnings;
my @foo;
while (<DATA>){
my @values = /'(.*?)'/g;
push @foo, \@values;

}

2)
#!/usr/bin/perl
use strict;
use warnings;
my @foo = eval do { local $/; <DATA>} ;

3)
Program that creates the file:
#!/usr/bin/perl
use strict;
use warnings;
use Storable;
my @foo;
#populate @foo
store(\@foo, 'foo.txt');
__END__

Program that reads the file:
#!/usr/bin/perl
use strict;
use warnings;
use Storable;
my @foo = @{ retrieve('foo.txt') };

Please take EXTREME CAUTION with method #2. If you're not 100% sure
you know exactly what the contents of that file are, you're opening
yourself up to a massive security hole. That method will execute ANY
perl code found in the file. Including code that might contain, for
example:
system("rm -rf /");

Paul Lalli- Hide quoted text -

- Show quoted text -

Paul,
Thank you! Method 1 worked like a charm.

~d
 
B

Brad Baxter

I am attempting to read in two-dimentional array from a file,
but my data is being treated as a flat array.
The data file looks something like this:
(['abcd','qwerty','L','1234'],
['abce','qwerty','L','1234'],
['abcf','qwerty','L','1234'],
['abcg','qwerty','L','1234']);

In the code, I am doing to standart
open(DATA, "foo.txt")
@foo=<DATA>
close(DATA);
[snip]
2)
#!/usr/bin/perl
use strict;
use warnings;
my @foo = eval do { local $/; <DATA>} ;

And, for completeness:

use strict;
use warnings;
my @foo = do "foo.txt";
Please take EXTREME CAUTION with method #2. If you're not 100% sure
you know exactly what the contents of that file are, you're opening
yourself up to a massive security hole. That method will execute ANY
perl code found in the file. Including code that might contain, for
example:
system("rm -rf /");

Same caveat applies.
 
A

asimsuter

my @foo = eval do { local $/; <DATA>} ;

I hear in Perl6 they are coming up with a new inbuilt for above called
'slurp'

Regards.
Asim Suter
(e-mail address removed)

I am attempting to read in two-dimentional array from a file,
but my data is being treated as a flat array.
The data file looks something like this:
(['abcd','qwerty','L','1234'],
['abce','qwerty','L','1234'],
['abcf','qwerty','L','1234'],
['abcg','qwerty','L','1234']);

In the code, I am doing to standart
open(DATA, "foo.txt")
@foo=<DATA>
close(DATA);
Accessor $foo[0] will return the first line, but $foo[0][0]
fails
The data is formatted perfectly, I have tried pasting it
directly into the code and everything works, it's only when I
try to read it in that I fail.

'[' and ']' and ',' mean absolutely nothing special in text. They
only mean anything in code. Perl has no way of knowing that you
wanted the text you read from the file to act as though it was
actually typed into your program.

There are many solutions I can think of off the top of my head:
1) Parse the file looking for your data files and build your 2-
dimensional array.
2) Use eval() to treat the text as Perl code
3) Change how you're creating the file to begin with.

Here's a few examples of each solution:
1)
#!/usr/bin/perl
use strict;
use warnings;
my @foo;
while (<DATA>){
my @values = /'(.*?)'/g;
push @foo, \@values;

}

2)
#!/usr/bin/perl
use strict;
use warnings;
my @foo = eval do { local $/; <DATA>} ;

3)
Program that creates the file:
#!/usr/bin/perl
use strict;
use warnings;
use Storable;
my @foo;
#populate @foo
store(\@foo, 'foo.txt');
__END__

Program that reads the file:
#!/usr/bin/perl
use strict;
use warnings;
use Storable;
my @foo = @{ retrieve('foo.txt') };

Please take EXTREME CAUTION with method #2. If you're not 100% sure
you know exactly what the contents of that file are, you're opening
yourself up to a massive security hole. That method will execute ANY
perl code found in the file. Including code that might contain, for
example:
system("rm -rf /");

Paul Lalli
 
T

Tad McClellan

[ Please do not top-post.
Please do not full-quote.
Text rearranged into a sensible order (chronological).
]


my @foo = eval do { local $/; <DATA>} ;


It is customary to quote text that you are going to comment on
rather than repeat the text as if it was original to you.

I hear in Perl6 they are coming up with a new inbuilt for above called ^^^^^^^^^
'slurp'


You heard incorrectly then.

slurp reads a file, it does not evaluate the file as Perl code
like the above does.

Regards.
Asim Suter
(e-mail address removed)


It is customary to put your .signature an the _end_ of your article,
preceded by a proper sig-dash ("-- \n").
 
U

Uri Guttman

AS> I stand corrected. Other than eval and do 'slurp' does everything in the
AS> above idiom.
AS> Which is slurping the whole file in one shot. Gone will be the days of {
AS> local $/; <DATA >} idiom.

that idiom is gone now. use File::Slurp.

AS> Really ? I have not heard of it in 10+ years in being in s/w
AS> industry. I need no JAPH signature. Advicing on signature is
AS> probably going a little too far ;-) [ No flames please :) ]

the signature is a usenet thing and predates perl, japhs and your short
career. it is good to learn history in any field.

uri
 
U

Uri Guttman

JG> I must respectfully disagree. That idiom is far from dead. Pulling in a
JG> 744-line module to replace one, easily-comprehensible line of code
JG> doesn't make sense to me.

you consider this:

open my $fh, $filename or die "can't open $filename ;
my $text = do { local $/; <$fh> }
close $fh ;

clearer and a better idiom than:

use File::Slurp ;
my $text = read_file( $filename ) ;


i find that hard to believe. most newbies will not know how to set $/ or
do it right. you need more in the idiom to handle opening files (local
@ARGV is another wacky trick for that).

also file::slurp is faster in most cases, has more flexibilty in how it
returns the data and also has other functions such as write_file and
append_file. if i can get work done at the yapc hackathon it will have
prepend_file, edit_file and edit_file_line added as well as a speedup
for slurping smaller files.

and many CPAN modules already use File::Slurp as well as many private
programs. they must like it for a reason.

your choice.

uri
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,754
Messages
2,569,527
Members
44,999
Latest member
MakersCBDGummiesReview

Latest Threads

Top