For Programmers: Free Programming Magazines  


Home > Archive > PERL Miscellaneous > April 2005 > Simple file open to an Array of Arrays









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Simple file open to an Array of Arrays
craig.carl@gmail.com

2005-04-26, 8:58 am

All -
I am following the instructions in Programming Perl (270-271) almost
to the letter, but I still cannot get this to work. I get these errors:

Can't use string ("1") as a symbol ref while "strict refs" in use at
collect2.pl line 11.

or

Can't use string ("") as a symbol ref while "strict refs" in use at
collect2.pl line 11.

data.txt looks like this;
string11, string12, string13
string21, string22, string23
string31, string32, string33
string41, string42, string43


#!/usr/bin/perl

use strict;
use warnings;

my(@AoA) = { };
my($file) = "";
my($line) = "";

#OR next line can read - open(@AoA, "/data.txt") - different error.
open($file, "/data.txt");
while (<> )
{
push @AoA, [split /,/];
}

for $line (@AoA) {
print "@$line\n";
}

I am trying to print out the contents of the array.

Thanks,

C

Mark Clements

2005-04-26, 8:58 am

craig.carl@gmail.com wrote:
> All -
> I am following the instructions in Programming Perl (270-271) almost
> to the letter, but I still cannot get this to work. I get these errors:
>
> Can't use string ("1") as a symbol ref while "strict refs" in use at
> collect2.pl line 11.
>
> or
>
> Can't use string ("") as a symbol ref while "strict refs" in use at
> collect2.pl line 11.
>
> data.txt looks like this;
> string11, string12, string13
> string21, string22, string23
> string31, string32, string33
> string41, string42, string43
>
>
> #!/usr/bin/perl
>
> use strict;
> use warnings;
>
> my(@AoA) = { };
> my($file) = "";
> my($line) = "";
>
> #OR next line can read - open(@AoA, "/data.txt") - different error.
> open($file, "/data.txt");
> while (<> )
> {
> push @AoA, [split /,/];
> }
>
> for $line (@AoA) {
> print "@$line\n";
> }
>


You are opening data.txt and storing the filehandle in $file. You are
then reading from default input <> (which is stdin if you supply no
arguments on the command line).

Try

open $file,"</data.txt" or die $!;

while($_=<$file> ){
blah blah
}

Though it would be more normal to use the filehandle directly:

open INFILE,"</data.txt" or die !;

while(<FILE> ){

blah


It is very important to test the return values of your system calls eg open.

regards,

Mark
John Bokma

2005-04-26, 3:59 pm

Mark Clements wrote:

> open $file,"</data.txt" or die $!;
>
> while($_=<$file> ){
> blah blah
> }
>
> Though it would be more normal to use the filehandle directly:


open my $fh, "/data.txt" or die $!;

is something I personally prefer over:

> open INFILE,"</data.txt" or die !;


( I also drop the <, since it's the default).

But also, I close explicitly, instead of letting $fh go out of scope.

--
John Small Perl scripts: http://johnbokma.com/perl/
Perl programmer available: http://castleamber.com/
Happy Customers: http://castleamber.com/testimonials.html

Gunnar Hjalmarsson

2005-04-26, 3:59 pm

Mark Clements wrote:
> craig.carl@gmail.com wrote:
>

Do you know what you are doing here? You make the first element in @AoA
a hash reference, which makes no sense. Should better be:

my @AoA = ();

or simply

my @AoA;
[color=darkred]

Here you initialize $file to be a plain string...
[color=darkred]

.... and here you try to use it as something else.

Drop the separate declaration, and say:

open my $file, '<', '/data.txt' or die $!;
[color=darkred]
>
> You are opening data.txt and storing the filehandle in $file. You are
> then reading from default input <> (which is stdin if you supply no
> arguments on the command line).
>
> Try
>
> open $file,"</data.txt" or die $!;
>
> while($_=<$file> ){
> blah blah
> }


That doesn't help much if $file is a plain string.

--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl
Chris Mattern

2005-04-26, 3:59 pm

craig.carl@gmail.com wrote:

> All -
> I am following the instructions in Programming Perl (270-271) almost
> to the letter, but I still cannot get this to work. I get these errors:
>
> Can't use string ("1") as a symbol ref while "strict refs" in use at
> collect2.pl line 11.
>
> or
>
> Can't use string ("") as a symbol ref while "strict refs" in use at
> collect2.pl line 11.
>
> data.txt looks like this;
> string11, string12, string13
> string21, string22, string23
> string31, string32, string33
> string41, string42, string43
>
>
> #!/usr/bin/perl
>
> use strict;
> use warnings;
>
> my(@AoA) = { };
> my($file) = "";



This is your problem. You shouldn't initialize variables that
you're going to use going to use as lexical filehandles. Let
the open autovivify it. Lose this line.

> my($line) = "";


In fact, *all* this initialization is pointless, and the declarations
are premature. Lose 'em all.
>
> #OR next line can read - open(@AoA, "/data.txt") - different error.


Well, yes. Open requires a filehandle or a scalar with a lexical
filehandle for its first argument. An array is not legal and will
produce an error.

> open($file, "/data.txt");


Always, yes, ALWAYS check to see if an open succeeds. This is also
where you should declare $file. Make this:

open(my $file, "/data.txt")
or die("Couldn't open /data.txt: $!. Stopped ");

Your "my @AoA;" should go here.

> while (<> )


This reads STDIN, or a list a files you provided on the command line.
You want to read the file you opened to the filehandle $file:

while (<$file> )

> {


Unless you *want* the last element of each anonymous array to have a
newline at its end, you probably want a:

chomp;

here.

> push @AoA, [split /,/];


This is the part you worried about, and it shows. You did it right.

> }
>
> for $line (@AoA) {


This is where you declare $line; always declare things at the last minute
and in the smallest possible scope.

for my $line (@AoA) {

> print "@$line\n";


And you did this part right, too.

> }
>
> I am trying to print out the contents of the array.
>
> Thanks,
>
> C


--
Christopher Mattern

"Which one you figure tracked us?"
"The ugly one, sir."
"...Could you be more specific?"
Chris Mattern

2005-04-26, 3:59 pm

Mark Clements wrote:

> craig.carl@gmail.com wrote:
>
> You are opening data.txt and storing the filehandle in $file.


No, he's not. That's what's causing his error. He's opening data.txt
and trying to use "" as a filehandle, because that's what's in $file.
Open is not creating a filehandle to put in $file because it already
has a value.

> You are
> then reading from default input <> (which is stdin if you supply no
> arguments on the command line).


This is indeed an error, but that's not what's making his program
fail on the open.

>
> Try
>
> open $file,"</data.txt" or die $!;


A little more explanation on the die would be nice. It will still
fail if he puts "" in $file before executing this.

>
> while($_=<$file> ){


just "while (<$file> )" will do.

> blah blah
> }
>
> Though it would be more normal to use the filehandle directly:
>
> open INFILE,"</data.txt" or die !;


"or die $!;"

That would solve his problem. But lexical filehandles have a lot of
advantages (you can pass them as an argument to subroutines, for one),
and there aren't any big drawbacks to them. In modern Perl, you should
use them instead of the old-fashioned filehandles, which is why I
advised him on how to make the lexical work instead of suggesting this.
>
> while(<FILE> ){


Don't you mean "while (<INFILE> )"?
>
> blah
>
>
> It is very important to test the return values of your system calls eg
> open.


Very true, and good advice.
>
> regards,
>
> Mark


--
Christopher Mattern

"Which one you figure tracked us?"
"The ugly one, sir."
"...Could you be more specific?"
craig.carl@gmail.com

2005-04-26, 8:57 pm

All - Thanks for ALL your help, I got it. I remove all of the || die
error checking when I post to make it easier to read. Here is the
script as it works -
#!/usr/bin/perl

use strict;
use warnings;


my @AoA = ();

open(my $file, "/home/craig/Boeing_EMCC4798/perl/celerras.txt");
while (<$file> )
{
push @AoA, [split /,/];
}

for my $line (@AoA) {
print "@$line";
}

Joe Smith

2005-04-28, 4:00 am

craig.carl@gmail.com wrote:
> I remove all of the || die
> error checking when I post to make it easier to read.


Don't do that.
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2009 codecomments.com