Question

this is first my perl script

http://bpaste.net/show/171137/

#!/usr/bin/perl

#This program will take a user's input and then count how many letters there are. Whereupon it will count the number of unique letters before printing all the data
#back to the user.

use strict;
use warnings;

#======================================================================================================================
# This section is to collect and spit back the input to the user.
#======================================================================================================================

print "\n\nHello, please enter a word, a phrase, or a sentence. Press Enter when you are done.\n";
my $input = <>; #Collecting the input from the user.
chomp $input; #Chomping, or removing, the \n from the end of the input.
print "\nYou typed -:[$input]\n";

#======================================================================================================================
#This section will find how many unique characters there are.
#======================================================================================================================
my @uniqueArray;
my @stringArray = split(// , $input); 
my $x = 0;
my $string_max_index = $#stringArray;

for($stringArray[$x];$stringArray[$string_max_index];$x++)
{
    my $found = 0;
    my $test = $stringArray[$x];
    my $y = 0;

    for($uniqueArray[$y];$uniqueArray[$#uniqueArray];$y++)
    {
        if($test eq $uniqueArray[$y])
        {
            $found=1;
        }
    }

    if($found eq 1)
    {
        $uniqueArray[$#uniqueArray] = $stringArray[$x];
    }
}   

#======================================================================================================================
# This section will determine how many ascii characters are in the $input variable and output the results of this
# program.
#======================================================================================================================

my $numOfLet = 0;
while ( $input ne "" )
{
    $numOfLet = $numOfLet + 1;
chop $input
}

print "Total Characters -: $numOfLet"; 
print "Total of Unique Characters -: $#uniqueArray \n\n\n";

exit;

I was able to get rid of all the errors except for these two,

Useless use of array element in void context at letter_counter.pl line 38
Useless use of array element in void context at letter_counter.pl line 44

What is confusing me is that There is nothing at those lines, just the closing brackets for my for loop, which leads me to believe that the issue is an element I called in each for loop.

Was it helpful?

Solution

The initialization block of your for loop is the immediate culprit. Adjusting to something like this resolves the warning:

for(;$stringArray[$string_max_index];$x++)

Otherwise you're accessing a value, but doing... nothing with it? That's what the warning is for.

I spot a few other problems, though:

  • Your for loops are... a little funny, I don't know how else to put that.
  • Array length is usually easiest to read with the scalar keyword.
  • Adding members to an array is usually done with the push keyword.

Using the above in combination:

for(my $x = 0; $x < scalar @stringArray;$x++)
{
    my $found = 0;
    my $test = $stringArray[$x];
    my $y = 0;

    for (my $y = 0; !$found && $y < scalar @uniqueArray;$y++)
    {
        if($test eq $uniqueArray[$y])
        {
            $found=1;
        }
    }

    unless ($found)
    {
        push @uniqueArray, $stringArray[$x];
    }
}

If the above for loops don't look sensible to you, now is a good time to look up some tutorials.

This could be simplified with foreach loops:

foreach my $letter (@stringArray) {
    ...
}

Or with grep searches:

my $found = grep { $_ eq $letter } @uniqueArray;

But, in the particular case of counting unique values, it's often simplest to assign to a hash:

my %uniques;
$uniques{$_} = 1 for @stringArray;
my $num_uniques = scalar keys %uniques;

Combining all of that:

my @letters = split(//, $input);        #split input into array of chars
my %uniques;                            #declare empty hash
$uniques{$_} = 1 for @letters;          #set hash key for each char
my $num_letters = scalar @letters;      #count entries in letter list
my $num_uniques = scalar keys %uniques; #count unique keys in letter hash

Exercise for the reader: adjust the above code so that it counts the number of times each character is used.

OTHER TIPS

That's because @uniqueArray is empty...

Given this short example:

use strict;
use warnings;

my @arr;
my $t = 0;

for ($arr[$t]; $arr[$#arr]; $t++ ) {
    print "no\n";
}

__OUTPUT__
Useless use of array element in void context at t.pl line 11.

You declare my @uniqueArray; at line 21 and never do anything with it...

Which also means how will this ever match at line 34?

if($test eq $uniqueArray[$y]) 

Again, @uniqueArray is an empty array.

To fix your script (although please look at rutter's hash suggestion), you can do the following. Remove:

my $x = 0;
my $y = 0;

Instead of using C-style loops, replace with the following:

for my $x (0 .. $string_max_index )

for my $y (0 .. $#uniqueArray)

Lastly, use the following:

if(!$found)
    {
        push @uniqueArray, $stringArray[$x];
    }

Hope this helps!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top