FAQ
Hello Perl community,

I am trying to get a simple program working that will count the words in a
text file and put them in a hash with the key being the word and the value
being its frequency in the text file. Here is my code:

---

#!/usr/bin/perl
use strict;
use warnings;

{

open IN, "<file.txt" or die "cannot open file: $!";

my %word_count;
my @input_file = <IN>;

foreach (@input_file){

my @x = split;


foreach (@x){


$word_count{$_}++;

}
}

foreach (%word_count){
print "$word_count{$_}\n\n";
}
}
---

The problem is on the 3rd to last line I get this error when I run it:

Use of uninitialized value within %word_count in concatenation (.) or string
at perl.pl line 26, <IN> line 520.

I don't understand why any value would be unintialized in that hash as the
loops previous should have taken care of all the initializing and word
counts. If I remove the last foreach loop and just put a common word for
ex.: print "$word_count{the}\n" I get the count for that word.

Thanks,

Jon

Search Discussions

  • John SJ Anderson at Jun 8, 2011 at 3:35 pm
    On Wed, Jun 8, 2011 at 11:30, Jon Forsyth wrote:

    This part:
    foreach (%word_count){
    print "$word_count{$_}\n\n";
    }
    You want to write like this:

    foreach my $key ( keys %word_count ) {
    print "$word_count{$key}\n\n";
    }

    What you've got above is getting both keys *and* values from the hash,
    and you're getting that error when values are used as keys in the
    lookup.

    chrs,
    john.
  • Rob at Jun 8, 2011 at 4:41 pm

    On 08/06/2011 16:30, Jon Forsyth wrote:
    Hello Perl community, Hey Jon
    I am trying to get a simple program working that will count the words in a
    text file and put them in a hash with the key being the word and the value
    being its frequency in the text file. Here is my code:

    ---

    #!/usr/bin/perl
    use strict;
    use warnings;
    Well done. Those two lines work magic.
    {
    This will work fine, but enclosing your code in a block as you would in
    C or Java is unnecessary. The source file as a whole constitutes a code
    block for the purposes of scoping, and you will make Perl programmers
    feel more at home if you drop the braces.
    open IN, "<file.txt" or die "cannot open file: $!";
    Whatever your books may say, best practice is to use lexical file
    handles and the three-argument form of open. So this line would become

    open my $in, '<', 'file.txt' or die "cannot open file: $!";
    my %word_count;
    my @input_file =<IN>;

    foreach (@input_file){
    Reading the file one line at a time, there is no need for @input_file,
    and your loop becomes just

    while (<$in>) {

    my @x = split;


    foreach (@x){
    $word_count{$_}++;

    }
    Trivially, there is no need for @x here (and in any case it deserves a
    better name!) so you could write

    $word_count{$_}++ foreach split;
    }

    foreach (%word_count){
    print "$word_count{$_}\n\n";
    }
    }
    ---

    The problem is on the 3rd to last line I get this error when I run it:

    Use of uninitialized value within %word_count in concatenation (.) or string
    at perl.pl line 26,<IN> line 520.

    I don't understand why any value would be unintialized in that hash as the
    loops previous should have taken care of all the initializing and word
    counts. If I remove the last foreach loop and just put a common word for
    ex.: print "$word_count{the}\n" I get the count for that word.
    While you can 'foreach' over an entire hash, you will be iterating over
    (key, value, key, value ...) alternately in the body of the loop. The
    errors come from the times when $_ holds a hash value instead of a key.
    Since there is no corresponding hash entry, $word_count{$_} does not
    exist and is reported as being uninitialized.

    What you wanted here was

    foreach (keys %word_count) {
    print "$word_count{$_}\n";
    }

    but I recommend that you use the built-in library Data::Dumper to
    examine data structures for debugging. Just write

    use Data::Dumper;
    print Dumper \%word_count;

    and you will see the hash that you have built.

    Cheers,

    Rob

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupbeginners @
categoriesperl
postedJun 8, '11 at 3:30p
activeJun 8, '11 at 4:41p
posts3
users3
websiteperl.org

People

Translate

site design / logo © 2021 Grokbase