Reputation: 15
I would like to input data from a list in Perl. So far, I have been pasting lists of data into the actual program for it to process. My original sorting program looked like this:
# /perl/bin
use strict; #force perl to code properly
use warnings; #find typing mistakes in program like missing semicolons, etc.
use Text::ParseWords; #parse text into an array of tokens or array of arrays
my @rows;
while (<DATA>) {
push @rows, [ parse_line(',', 0, $_) ];
}
@rows = sort { $a->[2] <=> $b->[2] } @rows;
open OUTPUT, ">OUTPUT.TXT";
foreach (@rows) {
print OUTPUT join ',', @$_;
}
__DATA__
SMITH,M,1
JONES,F,1
...
But I would like to have it input from a file that has this list instead. I'm not sure if I'm even on the right track but this is what I have so far:
# /perl/bin
use strict; #force perl to code properly
use warnings; #find typing mistakes in program like missing semicolons, etc.
use autodie; #replace functions with ones that succeed or die with lexical scope
use Text::ParseWords; #parse text into an array of tokens or array of arrays
open(MYINPUTFILE, "<inputfile.txt"); # open for input
my @rows = <MYINPUTFILE>; # read file into list
while (<MYINPUTFILE>) {
push @rows, [ parse_line(',', 0, $_) ];
}
@rows = sort { $a->[2] <=> $b->[2] } @rows;
open OUTPUT, ">OUTPUT.TXT";
foreach (@rows) {
print OUTPUT join ',', @$_;
}
Upvotes: 0
Views: 629
Reputation: 13914
Here's the crux of your problem:
open(MYINPUTFILE, "<inputfile.txt"); # open for input
my @rows = <MYINPUTFILE>; # read file into list
Since "@rows =" gives a "wantarray" or list context to the right-hand side, "<>" reads the entire file.
Then:
while (<MYINPUTFILE>) { # try to read file again,
# but you've already read it all
push @rows, [ parse_line(',', 0, $_) ];
}
You're trying to read the file twice.
There are other issues with your code, but you probably meant to write only:
open(MYINPUTFILE, "<inputfile.txt"); # open for input
my @rows;
while (<MYINPUTFILE>) {
push @rows, [ parse_line(',', 0, $_) ];
}
… by parallel to your earlier version.
At the least, you might consider a couple of Perlish changes;
open my $input_file, '<', 'inputfile.txt';
Using a lexical ("my") variable instead of a *FILEHANDLE is nicer in any more complex situation than this one. (Among other things, you can pass it to a subroutine much more easily.) Using the three-argument form of open
also protects you against problems if you allow others to specify the filename to your program. You then would use <$input_file>
in your while
loop.
Upvotes: 1