Reputation: 15
I have a file that I wish to search for strings, matching with items stored in an array. I open the file, loop through it and when I find what I'm looking for, I change a variable flag so additional work can be done. I am having an issue where the variable I set is not sticking. I placed the variable within the foreach loop, made it an our
variable, to no avail.
Questionable code:
my $zed = 0;
foreach my $SUB (@sub) {
print "We are currently looking for $SUB<br><br>";
open (my $input, "<", "C:\\Users\\scottbro\\Desktop\\PMS.txt")
or die "Cannot open PMS.txt: $!";
our $flag = 0;
##SET Zed to keep track of where we are
print "Zed is $zed<br>Flag is $flag<br>";
$zed++;
while (<$input>) {
print "inside the while loop, flag is now $flag<br>";
## IF you find what you are looking for, set flag to 1
if (/$SUB/) {
$flag = 1;
print "Found sub property, flag is now $flag<br>";
## IF flag is 1, and line has email address, show it!
} elsif ($flag = 1 && /<email>(.+)/) {
print "Flag is $flag, email is $1<br>";
}
}
close($input);
}
Output, where it can be seen the flag variable loses value:
We are currently looking for Property 1
Zed is 0
Flag is 0
inside the while loop, flag is now 0
inside the while loop, flag is now
Flag is 1, email is email1
inside the while loop, flag is now 1
Flag is 1, email is email2
inside the while loop, flag is now 1
inside the while loop, flag is now
inside the while loop, flag is now
inside the while loop, flag is now
Found sub property, flag is now 1
inside the while loop, flag is now 1
Flag is 1, email is email3
inside the while loop, flag is now 1
Flag is 1, email is email4
inside the while loop, flag is now 1
inside the while loop, flag is now
inside the while loop, flag is now
Flag is 1, email is email 5
Upvotes: 1
Views: 144
Reputation: 126722
You are assigning to $flag
in your test
elsif ( $flag=1 && /<email>(.+)/ ) { ... }
is setting $flag
to 1 && /<email>(.+)/
which is false if the regex pattern doesn't match
It should probably be
if ( $flag and /<email>(.+)/ ) { ... }
I suggest you forget about $flag
and instead use the fact that the input file will be at eof if $sub
hasn't been found, so the program won't be able to read anything further anyway
It's also nicer to rewind the file rather than reopen it. It's almost certain that the data should be parsed into a hash and accessed directly, but I can't tell for sure with the little information you give
my @sub;
open my $fh, '<', 'C:\Users\scottbro\Desktop\PMS.txt' or die "Cannot open PMS.txt: $!";
for my $sub ( @sub ) {
seek $fh, 0, 0;
while ( <$fh> ) {
last if /$sub/;
}
while ( <$fh> ) {
next unless /<email>(.+)/;
print qq{Email for "$sub" is "$1"};
last;
}
}
Upvotes: 4
Reputation: 385897
You are assigning to $flag
in your test rather than checking its value.
elsif ($flag = 1 && /<email>(.+)/)
should be
elsif ($flag == 1 && /<email>(.+)/)
Or even better,
elsif ($flag && /<email>(.+)/)
That said, repeatedly reading the same file is quite inefficient. Here's a version that doesn't.
my $pat = join '|', map quotemeta, @subs;
my $qfn = 'C:\\Users\\scottbro\\Desktop\\PMS.txt';
open(my $fh, '<', $qfn)
or die(qq{"Can't open "$qfn": $!\n"});
while (<$fh>) {
my ($sub) = /($pat)/
or next;
defined( $_ = <$fh> )
or last;
my ($email) = /<email>(.+)/
or redo;
print(qq{Email for "$sub" is "$email"\n});
}
Upvotes: -2