Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Is this a correct way of obtaining input from a file?

by cecil36 (Pilgrim)
on Aug 06, 2002 at 20:38 UTC ( [id://188153]=perlquestion: print w/replies, xml ) Need Help??

cecil36 has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to get input from a file that has three pieces of information in it, a tracking number, a pager number, and the messaging service the pager is programmed on. The data is on separate lines, as in
tracking number pager number paging service
Below is how I'm getting the input.
$datafile = "CheckUPS.in"; open (DATAFILE, $datafile) or die "Input data not found.\n"; while (<DATAFILE>) { $TRACK = $_; chomp ($TRACK); $pager = $_; chomp ($pager); $service = $_; chomp ($service); } print "$TRACK $pager $service\n";
Here is where I'm generating the output file which a third-party program is going to read as input to generate the message to be sent to the pager. $status is the current status of the package, and $new is the current geographical location of the package when it was last scanned.
# Generate the outgoing notice, and send it if (!($old eq $new)) { open (FILE,">$WORKDIR/$MAILOUT") || die "Could not open file: $!\n +"; print FILE "MSG:\n"; print FILE "TO: $pager $service\n"; print FILE "CONTENTS: Package ID $TRACK is/was $status to $new\n" +; #print FILE "Status: $status\n"; #print FILE "Track#: $TRACK\n"; #print FILE "Old: $old\n"; #print FILE "New: $new\n"; print FILE "\n"; close (FILE); if (($PAGER)) { $PagerCmd = "echo \"Check UPS Tracking: $TRACK\" | $MAILBIN $P +AGER"; system "$PagerCmd"; } #$MailCmd = "cat $WORKDIR/$MAILOUT | $MAILBIN $EMAILS -s \"UPS Pac +kage Tracking: $status\""; #system "$MailCmd"; }
My last output file was
MSG: TO: Airtouch Airtouch CONTENTS: Package ID Airtouch is/was to
The paging service is listed as the recipient and the package ID number. For some reason, the status and location are not making it into the file as well. What should I check in my code?

Replies are listed 'Best First'.
Re: Is this a correct way of obtaining input from a file?
by DamnDirtyApe (Curate) on Aug 06, 2002 at 20:53 UTC

    As for getting input from the file, I'd say what you're doing is fine, though you could reduce it to:

    open FH, 'CheckUPS.in' or die "Couldn't open file: $!" ; chomp( my ( $TRACK, $pager, $service ) = <FH> ) ; close FH ;

    As for what you should check, I'd say make sure you're running under use strict, then trace those variables back to where they're assigned, as that's not shown in your code.


    _______________
    DamnDirtyApe
    Those who know that they are profound strive for clarity. Those who
    would like to seem profound to the crowd strive for obscurity.
                --Friedrich Nietzsche
      I tried a
      use strict
      a while back and the program puked at it. It works fine with out it. That could be a future revision is to rewrite this thing with
      use strict
      .

        How large is your program? If it's not too big, it's entirely possible that updating your script to use strict could be done with minimal effort, and would give you an added level of built-in error checking that can prevent things like mislabeled variables, etc.


        _______________
        DamnDirtyApe
        Those who know that they are profound strive for clarity. Those who
        would like to seem profound to the crowd strive for obscurity.
                    --Friedrich Nietzsche
Re: Is this a correct way of obtaining input from a file?
by myocom (Deacon) on Aug 06, 2002 at 21:30 UTC

    I can do you one better, if (as it appears) you're trying to get information about a UPS package that's en route somewhere.

    The Business::UPS module will allow you to query UPS and get back useful information. To quote from the POD:

    #!/usr/local/bin/perl use Business:UPS; %t = UPStrack("z10192ixj29j39"); $t{error} and die "ERROR: $t{error}; print "This package is $t{'Current Status'}\n"; # 'Delivered' or # 'In-transit' print "More info:\n"; foreach $key (keys %t) { print "KEY: $key = $t{$key}\n"; }
    "One word of warning: if you meet a bunch of Perl programmers on the bus or something, don't look them in the eye. They've been known to try to convert the young into Perl monks." - Frank Willison
Re: Is this a correct way of obtaining input from a file?
by thewalledcity (Friar) on Aug 06, 2002 at 20:58 UTC
    The problem is that you are getting the same value everytime you do an assignment for each run of the loop. For example:
    Sample data: foo bar baz First time through loop $TRACK = foo $pager = foo $service = foo Second time (etc) $TRACK now equals bar $pager now equals bar $service now equals bar etc..
    TIMTOWTDI but this would work..
    $datafile = "CheckUPS.in"; open (DATAFILE, $datafile) or die "Input data not found.\n"; @text = <DATAFILE>; close (DATAFILE); $TRACK = chomp($text[0]); $pager = chomp($text[1]); $service = chomp($text[2]); print "$TRACK $pager $service\n";
Re: Is this a correct way of obtaining input from a file?
by Bird (Pilgrim) on Aug 06, 2002 at 21:11 UTC
    The problem is in how you're assigning data to your variables in your while loop...
    while (<DATAFILE>) { $TRACK = $_; chomp ($TRACK); $pager = $_; chomp ($pager); $service = $_; chomp ($service); }
    Here you're assigning $_ to three different variables before you even read the next value from your file. This means that in each interation of your while loop (i.e. for each value in the file), you assign that line to each variable. Ultimately, the last line of the file gets assigned to all 3 variables, and you're left with the output you received.

    What you actually wanted to do was skip the while loop and either do...

    open (DATAFILE, $datafile) or die "Input data not found.\n"; chomp ($TRACK = <DATAFILE>); chomp ($pager = <DATAFILE>); chomp ($service = <DATAFILE>);
    ...or use DamnDirtyApe's version above, which I prefer. Just keep in mind that each time <DATAFILE> is accessed as a scalar, another line is read from the file, whereas each time $_ is accessed, you're simply retrieving the value of that variable (not the next value in the file).

    -Bird

      I used DamnDirtyApe's suggestion and it worked like a charm in getting the input. However, when it comes to querying UPS's website with the tracking number, Lynx passes back a bad request, probably because there's an invalid character still attached to the tracking number. How can I strip any unwanted characters out after the string has been chomped?
        Nevermind the orignal post, Notepad stuck the character in the file when I generated it. vi in Cygwin fixed it.
Re: Is this a correct way of obtaining input from a file?
by fuzzyping (Chaplain) on Aug 06, 2002 at 20:58 UTC
    The value of $_ isn't changing within the same loop. Therefore, the last possible entry from the file will be the last thing assigned (to all of your variables). There are many different ways of doing this... (this example has been tested and works properly):
    #!/usr/bin/perl -w use strict; open(DATAFILE, "testfile"); my @file_data; push(@file_data, $_) while (<DATAFILE>); my ($track, $pager, $service) = @file_data; chomp ($track, $pager, $service); print "Tracking Number: $track\n"; print "Pager Number: $pager\n"; print "Service: $service\n";

    -fp

    Update: Actually, I like DamnDirtyApe's version better. Same concept as mine, but shorter... simply assign your values in list context.
Re: Is this a correct way of obtaining input from a file?
by physgreg (Scribe) on Aug 06, 2002 at 20:55 UTC
    I would replace your first snippet with
    my @fields; while (<DATAFILE>) { chomp; push @fields, $_; }
    This will give you an array with the correct values. If you want to assign it to a variable, then do:
    my ($TRACK, $pager, $service) = @fields;
    I haven't tested this, but it should be ok!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://188153]
Approved by insensate
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (4)
As of 2024-04-24 21:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found