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

Hi, I can't seem to figure out why this code won't work I have the ip address in the file ipfile.txt, but I keep getting guest not found is there something I am over looking?
#!/usr/bin/perl -w my (@ipfconts, $ipfile, $x); $remote_addr = '63.103.135.132'; $ipfile = '../ipfile.txt'; open (IPFILE, "<$ipfile") || die("Could not open $ipfile: $!\n"); @ipfconts = <IPFILE>; for ($x=0; $x<=$#ipfconts; $x++) { if ($ipfconts[$x] =~/$remote_addr}/){ print "added new guest!\n"; last; }else{ print "guest not found!\n";last; } }

Replies are listed 'Best First'.
Re: for loop
by Abigail (Deacon) on Jun 22, 2001 at 05:05 UTC
    A few points:
    • First, your regular expression looks fishy: /$remote_addr}/. Are you sure you need the } there?
    • Your regular expression isn't anchored. It will also give a match if it finds 163.103.135.132 in the file. Or, for that matter, 63010311352132, because . has a special meaning in regular expressions. You should probably use index, or perhaps eq, depending on what is in ipfile.txt.
    • You only check the first line of the file - if that is not a match, you exit the loop.
    • There is no need to read in the entire file into an array, and then loop over the array. And if you loop over an array, use Perl idiom, not C idiom. Here's how I would write it:
      open my $file => "<", $ipfile or die "Open: $!"; my $found; while (<$file>) { next if -1 == index $_ => $remote_addr; print "Added new guest\n"; $found = 1; last; } print "Guest not found\n" unless $found;
      If I did need the array (in other parts of the program), I would write the loop as:
      my $found; foreach (@ipfconts) { next if -1 == index $_ => $remote_addr; print "Added new guest\n"; $found = 1; last; } print "Guest not found\n" unless $found;

    -- Abigail

      open my $file => "<", $ipfile or die "Open: $!";

      I recognize the open above, but am curious why you're using the => instead of the comma. I realize they are synonymous. I was just curious why you chose that form over:

      open my $file, '<', $ipfile or die "Open: $!";

      Charles K. Clarkson

      Curiosity was framed. Ignorance killed the cat.
        To make the first argument stand out more, visually separating it from the other arguments. I do that a lot, with functions like push, substr, sprintf, flock, etc.

        -- Abigail

      The } was a typo. Thanks for clearing that up for me I hit myself on the head when I realized what I did.
Re: for loop
by japhy (Canon) on Jun 22, 2001 at 04:24 UTC
    You're exiting the loop too soon. You can't know if the guest isn't found until you've gone through the entire loop.
    my $found; open IPFILE, "< $ipfile" or die "couldn't read $ipfile: $!"; while (<IPFILE>) { last if $found = /\Q$remote_addr\E/o; } close IPFILE; if ($found) { print "user found!\n" } else { print "user not found!\n" }


    japhy -- Perl and Regex Hacker
Re: for loop
by Zaxo (Archbishop) on Jun 22, 2001 at 04:09 UTC

    Typo:

    - if ($ipfconts[$x] =~/$remote_addr}/){ + if ($ipfconts[$x] =~/$remote_addr/){

    Update: To clarify, the right paren inside // appears to be extraneous (unless that's a feature of your data file and intended). Props to crazyinsomniac.

    After Compline,
    Zaxo