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

I'm having problems with my code and cant quite figure it out. Here's my problem. I wrote a program that goes through and reads each line in a file and then takes that line and send it to a sub routins which contains some sql statements. But each time it gets to the end of the file it tries to run the blank data at the end of the file (the last line) and it ends up sending me errors. SO my question to all of you is how do I make my program stop once it has reached the end of the file and not to send the blank line to the sql section of my program. Below is my code
sub main{ my $log_parsing_files = "/export/home/fio/log_parsing_files"; opendir(FILES,"$log_parsing_files") || die "could not open $log_parsing_files"; #opens directory foreach $name (sort readdir(FILES)) { next unless ($name =~ /\w+\d*$/); &parsefile($name); } } sub parsefile { my $name = shift; my $line; my $value; open (FHIN, "</export/home/fio/log_parsing_files/ $name") || die ("can't open $name for reading.\n"); while (<FHIN>) { $line=$_; #chomp(); $line=~m%(\d+).*%; $line=~s/\s//g; &data_base_insert($line); print "these people where given there 5mb $line\n"; } close FHIN; } sub data_base_insert { my ($line) = @_; $sql = "SELECT user_seq from special_offers where user_seq = $line"; $cmd = $dbh->prepare($sql); $cmd->execute(); $userseq = $cmd->fetchrow; print "COMP: '$userseq' '$line'\n"; if ($userseq eq $line ) { print "There are already in the special offers table $line and $userseq\n"; } else { $sql = "INSERT INTO special_offers (PROMO, PROMODATE, USER_SEQ) VALUES ('XDRIVE', '19-JUNE-00','$line')"; $cmd = $dbh->prepare($sql); $dbh->commit(); $sql= "SELECT quota from user_quota where user_seq = $line"; $cmd = $dbh->prepare($sql); $cmd->execute(); $quota = $cmd->fetchrow; my $newspace= 5120 + $quota; my $sql = "UPDATE user_quota set quota = $newspace where user_seq=$line" ; $cmd = $dbh->prepare($sql); $cmd->execute(); $dbh->commit(); return $line; } }

Replies are listed 'Best First'.
Re: Closing program when end of files is reached
by maverick (Curate) on Jul 28, 2000 at 22:58 UTC
    Change:
    while (<FHIN>) { $line=$_;
    to this:
    while (<FHIN>) { $line=$_; next if $line =~ s/^\s*$/;
    This will cause the while loop to skip to the next iteration for lines which are blank or only contain whilespace. In your case it's only the last line, but you can never trust user supplied data :)

    /\/\averick

Re: Closing program when end of files is reached
by cwest (Friar) on Jul 28, 2000 at 22:54 UTC
    First off, your program does stop when it reaches the end of the file, that's just your trouble... you have a blank line just before the end of your file.

    Perhaps you should check if the line has anything in it and stop parsing?

    while (<FILE>) { last unless /^\n$/; do stuff(); }
    Enjoy!
    --
    Casey
    
RE: Closing program when end of files is reached
by chip (Curate) on Jul 29, 2000 at 01:46 UTC
    If you had expected this to do validation:
    $line = $_; $line=~m%(\d+).*%;
    ... then you would be mistaken. You could try this instead:
    ($line) = /(\d+)/ or next;

        -- Chip Salzenberg, Free-Floating Agent of Chaos

Re: Closing program when end of files is reached
by ferrency (Deacon) on Jul 28, 2000 at 22:58 UTC
    I sometimes short circuit while or for loops with something like:

    while (<FILE>) { chomp; s/^\s*#.*//; # remove comment-only lines next if /^$/; # skip blank lines (or, commented out lines) do_something_with($_); }
    This turns comment-only lines into blank lines, and then skips any blank lines in the file (not just the last line of the file).

    Is this what you're looking for?

    Alan