Dinesh
Dinesh

Reputation: 93

Perl while loop won't exit when blank line is entered

I am trying to print the sum, maximum, and minimum values of list of numbers but I am struggling to get it working.

When I press Enter the loop should exit but the program keeps running

use strict;
use warnings;

my @items;
my ( $sum, $max, $min );

while ( chomp( my $num = <STDIN> ) ) {
    last if ( $num eq '\n' );

    $max ||= $num;
    $min ||= $num;
    $sum += $num;

    $max = $num if ( $num > $max );
    $min = $num if ( $num < $min );

    push( @items, $num );
}

printf( "Entered numbers are: %s \n", join( ', ', @items ) );
print( "Sum of all numbers is : ", $sum );
print "\n";
print( "Minimum number is : ", $min );
print "\n";
print( "Maximum number is : ", $max )

Upvotes: 0

Views: 399

Answers (2)

Borodin
Borodin

Reputation: 126722

  • You can't use chomp inside a while condition like this

    while (chomp(my $num = <STDIN>)) { ... }
    

    because the while loop needs to terminate when the <> returns undef at end of file. So you must put the chomp as the first statement of the loop

  • The simplest way to exit a loop like this is to check whether the input contains any non-space characters using the regular expression /\S/

  • The check

    last if ( $num eq '\n' )
    

    won't work because you have used chomp to remove the newline from the input. Also, if you use single quotes '\n' is the two-character string \ followed by n. You need double quotes like "\n" to create a newline

  • When a scalar variable is first declared it has the value undef, so you can avoid any clumsy initialisation by testing for this and updating $min and $max unless the previous value is already defined and higher (or lower) than the new value

I would rewrite your program like this.

use strict;
use warnings;

my @items;
my ($sum, $max, $min);

while (my $num = <STDIN>) {
  chomp $num;
  last unless $num =~ /\S/;

  $max = $num unless defined $max and $max >= $num;
  $min = $num unless defined $min and $min <= $num;
  $sum += $num;
  push @items, $num;
}

print 'Entered numbers are: ', join(', ', @items), "\n";
print "Sum of all numbers is: $sum\n";
print "Minimum number is: $min\n";
print "Maximum number is: $max\n";

Upvotes: 2

choroba
choroba

Reputation: 241838

If you want to detect Enter, you can't chomp the input before. Also, '\n' is not the enter, you have to use double quotes "\n" to enable special characters.

The while (<>) loop is usually ended by Ctrl+D.

Moreover, you can find a module to do the work for you.

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

use List::Util qw{ max min sum };

my @items = <>;
chomp @items;
my $max = max(@items);
my $min = min(@items);
my $sum = sum(@items);

print "Entered numbers are: @items\n";
print "Sum of all numbers is: $sum\n";
print "Minimum number is: $min\n";
print "Maximum number is: $max";

Upvotes: 2

Related Questions