user7108016
user7108016

Reputation:

can't loop through the whole thing to start at the beginning after it shows your results

I am really new in perl and I am writing this program that gives you the unique words that are in a text file. however I don't know how to make it loop to ask the user for another file or to quit the program altogether.

I tried to put my whole code under a do until loop and it did not work

use 5.18.0;
use warnings;
use strict;

print "Enter the name of the file: ";
my %count;
my $userinput = <>; #the name of the text file the user wants to read
chomp($userinput); #take out the new line comand

my $linenumb = $ARGV[1];
my $uniqcount = 0;
#opens the file if is readeable
open(FH, '<:encoding(UTF-8)', $userinput) or die "Could not open file '$userinput' $!";
print "Summary of file '$userinput': \n";
my ($lines, $wordnumber, $total) = (0, 0, 0);
my @words = ();
my $count =1;

while (my $line = <FH>) {
   $lines++;
   my @words = split (" ", $line);
   $wordnumber = @words;

   print "\n Line $lines : $wordnumber ";
   $total = $total+$wordnumber;
   $wordnumber++;

}
print "\nTotal no. of words in file are $total \n";




#my @uniq = uniq @words;
#print "Unique Names: " .scalar @uniq . "\n";
close(FH);

Upvotes: 0

Views: 75

Answers (2)

Dave Cross
Dave Cross

Reputation: 69314

It's often a good idea to put complicated pieces of your code into subroutines so that you can forget (temporarily) how the details work and concentrate on the bigger picture.

I'd suggest that you have two obvious subroutines here that might be called get_user_input() and process_file(). Putting the code into subroutines might look like this:

sub get_user_input {
  print "Enter the name of the file: ";

  my $userinput = <>; #the name of the text file the user wants to read

  chomp($userinput); #take out the new line comand

  return $userinput;
}

sub process_file {
  my ($file) = @_;

  #opens the file if is readeable
  # Note: Changed to using a lexical filehandle.
  # This will automatically be closed when the
  # lexical variable goes out of scope (i.e. at
  # the end of this subroutine).
  open(my $fh, '<:encoding(UTF-8)', $file)
    or die "Could not open file '$file' $!";

  print "Summary of file '$file': \n";

  # Removed $lines variable. We'll use the built-in
  # variable $. instead.
  # Moved declaration of $wordnumber inside the loop.
  # Removed @words and $count variables that aren't used.
  my $total = 0;

  # Removed $line variable. We'll use $_ instead.
  while (<$fh>) {
    # With no arguments, split() defaults to
    # behaving as split ' ', $_.
    # When assigned to a scalar, split() returns
    # the number of elements in the split list
    # (which is what we want here - we never actually
    # use the list of words).
    my $wordnumber = split;

    print "\n Line $. : $wordnumber ";
    # $x += $y is a shortcut for $x = $x + $y.
    $total += $wordnumber;
    $wordnumber++;
  }

  print "\nTotal no. of words in file are $total \n";
}

And then you can plug them together with code something like this:

# Get the first filename from the user
my $filename = get_user_input();

# While the user hasn't typed 'q' to quit
while ($filename ne 'q') {
  # Process the file
  process_file($filename);
  # Get another filename from the user
  $filename = get_user_input();
}

Update: I've cleaned up the process_file() subroutine a bit and added comments about the changes I've made.

Upvotes: 3

daxim
daxim

Reputation: 39158

Wrap everything in a neverending loop and conditionally jump out of it.

while () {
    my $prompt = …
    last if $prompt eq 'quit';
    … # file handling goes here
}

Upvotes: 0

Related Questions