Edward Forgacs
Edward Forgacs

Reputation: 15

Input a list from a file in Perl

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

Answers (1)

BRPocock
BRPocock

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

Related Questions