distro distro - 17 days ago 5
Perl Question

Need suggestion with 'if' statement

I need help adjusting this block of my code. Everything was working but then it quit working and fails every time (prints). What am I doing wrong?

print "Enter a word to search for:";
chomp (my $word = <STDIN> );
if (not -e $word){
print "No such word found.\n";
exit;
}


Whole program.

#!/usr/bin/perl -w


use strict;


print "Welcome to the word frequency calculator.\n";
print "This program prompts the user for a file to open, \n";
print "then it prompts for a word to search for in that file,\n";
print "finally the frequency of the word is displayed.\n";
print " \n";


print "Please enter the name of the file to search:";
chomp (my $filename = <STDIN> );
if (not -e $filename){
print "No such file exists. Exiting program. Please try again.
+\n";
exit;
}


print "Enter a word to search for:";
chomp (my $word = <STDIN> );
if (not -e $word){
print "No such word found.\n";
exit;
}


print "Frequency of word: " . grep $word eq $_,
split /\W+/i, do { local (@ARGV, $/)= $filename; <> };


exit;

Answer
print "Welcome to the word frequency calculator.\n";
print "This program prompts the user for a file to open, \n";
print "then it prompts for a word to search for in that file,\n";
print "finally the frequency of the word is displayed.\n";
print " \n";

So, according to that, this program will...

  1. Ask the user for a file to search.
  2. Ask the user for a word to search for.
  3. Check how often that word is in that file.

You have the first part down.

print "Please enter the name of the file to search:";
chomp (my $filename = <STDIN> );
if (not -e $filename){
        print "No such file exists. Exiting program. Please try again.\n";
        exit;
}

Though it can be done a bit more succinctly by using die instead of print + exit. And generally rather than checking to see if a file exists you should just try to open a file. A file might exist but not be readable. Or it might exist when you checked and then be deleted when you later try to open it.

print "Please enter the name of the file to search: ";
chomp (my $filename = <STDIN> );
open my $fh, "<", $filename or die "Sorry, couldn't open $filename because $!";

Then for the second bit, you only need to prompt for the word. Checking whether the word exists as a filename is nonsense.

print "Enter a word to search for: ";
chomp (my $word = <STDIN> );

And, finally, reading the file and finding the word frequency. The code you're using for that is very hard to understand...

print "Frequency of word: " . grep $word eq $_,
  split /\W+/i, do { local (@ARGV, $/)= $filename; <> };

...it also slurps the whole file into memory which is inefficient if the file gets large.

Instead, read files line by line with a while loop. And instead of splitting the line into words, search through the line with /\Q$word\E/g. /g says to continue the search from the last place you matched.

my $frequency = 0;
while( my $line = <$fh> ) {
    while( $line =~ /\Q$word\E/g ) {
        $frequency++
    }
}

See perlretut for more info.

Comments