0

I tried to count the total number of words which are present in the file. The code below is showing 0 words as an output. Please help me fix this problem.

This code is saved in Countsample.pm:

package Countsample;

use strict;
use base"Exporter";
#use 5.010;

our @EXPORT=();
our @EXPORT_OK=qw(word_count);

sub word_count
{
    open(IP,"test1.txt");
    while(my $line=<>)
    my $word_count;


    my @words_on_line = split;
    $word_count+= @words_on_line;


    print"File contains $word_count words\n";
}

1;

Now in main program which is saved in Countsample1.pl:

#!/usr/bin/perl

use Countsample qw(word_count);
word_count();
exit;

The output I am getting is

syntax error at Countsample.pm line 14, near ")
my "
Global symbol "$word_count" requires explicit package name at Countsample.pm line 14.
Global symbol "$word_count" requires explicit package name at Countsample.pm line 18.
Global symbol "$word_count" requires explicit package name at Countsample.pm line 21.
Compilation failed in require at Countsample1.pl line 3.
BEGIN failed--compilation aborted at Countsample1.pl line 3.
Sinan Ünür
  • 113,391
  • 15
  • 187
  • 326
  • 2
    Posting a question on StackOverflow every time you get a syntax error isn't a great way to learn to program. You need to develop the analytical skills to fix these problems yourself. The error shows you where the problem is (well, within a line or two). What stops you taking a close look at those lines and working out what went wrong for yourself? – Dave Cross Mar 12 '15 at 15:57

3 Answers3

2

You need to give your program either a file or some input. E.g.

 perl Countsample1.pl Countsample.pm

will count the words in Countsample.pm

Also, you want while (my $line = <>) instead of the open. Did you notice how you never read from anything? I am assuming this is homework, so I am not going to post a completely re-written script.

Now, you must decide whether you are going to count words in just test1.txt, or anything given on the commandline or STDIN (that's what using <> means).

Assuming the latter, your word_count subroutine becomes rather simpler:

sub word_count {
    my $count;
    while (my $line=<>) {
        my @words_on_line = split ' ', $line;
        $count += @words_on_line;
    }
    print "File contains $count words\n";
    return; # don't accidentally use the return value of print as count
}

Of course, it would be better to just return the count from this subroutine and have the caller decide what to do with the return value.

PS: Your shebang line is wrong. It should be #!/usr/bin/perl if you want to use the system perl.

PPS: You don't need to inherit from Exporter. In most cases,

use Exporter qw( import );

is all you need.

PPPS: Don't export stuff by default. Instead, do:

our @EXPORT = (); # nothing is exported by default
our @EXPORT_OK = qw( word_count ); # word_count is exported if asked

and then use

use Countsample qw( word_count );

so you can invoke Countsample::word_count as just word_count.

Community
  • 1
  • 1
Sinan Ünür
  • 113,391
  • 15
  • 187
  • 326
2

There are some syntax errors in your script :

sub word_count {
    open(my $IP, '<', 'test1.txt') or die $!;
    #                              ^^^^^^^^^ always test the result of open                             
    my $word_count;
    # you must defined the counter outside of the while loop
    while(my $line=<$IP>) {
        #                 ^ you missed begin while bloc
        my @words_on_line = split ' ', $line;
        $word_count+= @words_on_line;
    } # and close while bloc
    # print the total outside of the loop
    print"File contains $word_count words\n";
}
Toto
  • 83,193
  • 59
  • 77
  • 109
1

Here's the error I get:

$ perl Countsample1.pl
syntax error at Countsample.pm line 14, near ")
    my "
Global symbol "$word_count" requires explicit package name at Countsample.pm line 14.
Global symbol "$word_count" requires explicit package name at Countsample.pm line 18.
Global symbol "$word_count" requires explicit package name at Countsample.pm line 21.
Compilation failed in require at Countsample1.pl line 1.
BEGIN failed--compilation aborted at Countsample1.pl line 1.

Lines 13 and 14 are:

while(my $line=<>)
my $word_count;

Your while loop needs a block of code. And blocks of code are delimited with braces. I think those lines (and the few following ones) should be:

my $word_count;
while(my $line=<>) {
    my @words_on_line = split;
    $word_count+= @words_on_line;
}

I've also moved my $word_count outside of the loop - you really don't want to reset it to zero on each loop iteration, do you?

Hmm.. now when I run it it just hangs. What could be wrong? That usually means either an infinite loop or a program waiting for input.

In this case, it's the program waiting for input.

while(my $line=<>)

This reads from STDIN (ok, yes, actually it reads from either STDIN or the files which have been passed on the command line - but there weren't any in this example, so STDIN it is). Presumably, you want it to read from the filehandle that have just opened. So use that instead.

while(my $line=<IP>)

Now it doesn't hang. But it says that my test file contains 0 words. And that's wrong.

Ah the problem is here. my $line=<IP> puts the line into $line. But you split the line with just split, which works on $_, not $line. Let's remove the my $line= so that the while loop puts the data into $_.

while (<IP>)

Now the program says that my file contains 5 words. Which is better than zero, but probably not right. So there's likely to be a logic problem.

Now you start debugging you logic...

Update: Actually, no. My file did contain only five words. So the logic is sound. Time to start adding more features. And perhaps modernising your code - for example replacing your old-style open() statement (open(IP,"test1.txt")) with something more modern (open my $ip, '<', "test1.txt")). Also check the return value from open() - open my $ip, '<', "test1.txt") or die $!.

Sinan Ünür
  • 113,391
  • 15
  • 187
  • 326
Dave Cross
  • 62,464
  • 3
  • 46
  • 83