npatel has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I am a perl novice, and am embarking on creating a perl script for work. The following test loop does not break when I input nothing and then press 'return', it just keeps looping. Something wrong? I can't see an issue:

print "Hello How are you?\n"; print "Please enter your reply here: "; $count=0; while (defined(chomp(@input[$count]=<STDIN>))) { print "\nYour entry was \"@input[$count]\""; $count++; }

Any help greatly appreciated!

Npatel

20090323 Janitored by Corion: Added formatting, code tags, as per Writeup Formatting Tips

Replies are listed 'Best First'.
Re: While(defined(STDIN)) does not break
by Corion (Patriarch) on Mar 21, 2009 at 11:53 UTC

    Even a line where you "input nothing but return" still contains the newline character. You need to close the input, usually by pressing CTRL+D (on unixish operating systems) or CTRL+Z (and then enter) (on Windows).

    Or you could change your loop to exit on a line that contains nothing but the newline character(s), which likely is more what you wanted.

Re: While(defined(STDIN)) does not break
by johngg (Canon) on Mar 21, 2009 at 13:40 UTC

    Further to Corion's advice, I have used this code structure in the past when prompting for user input that is terminated by CTRL+D (or CTRL+Z and ENTER). It clears away your last prompt before returning to the shell to make things look a bit tidier.

    use strict; use warnings; my $prompt = q{Please enter your response (CTRL+D to exit): }; my $dePrompt = qq{\r} . q{ } x ( length( $prompt ) + 2 ) . qq{\r}; my $responseCt = 0; while( 1 ) { print $prompt; last if eof STDIN; $_ = <STDIN>; chomp; $responseCt ++; print qq{Response $responseCt, "$_"\n}; } print $dePrompt;

    I hope this is of use.

    Cheers,

    JohnGG

Re: While(defined(STDIN)) does not break
by CountZero (Bishop) on Mar 21, 2009 at 13:49 UTC
    From perldoc -f chomp:
    It returns the total number of characters removed from all its arguments.
    chomp will always return a defined value.

    A better way to do what you want is:

    use strict; use warnings; use feature qw/say/; my @input; while (<>) { chomp; last unless $_; say "Your entry was: $_"; push @input, $_; }
    Or have a look at Prompt::ReadKey.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Re: While(defined(STDIN)) does not break
by Marshall (Canon) on Mar 22, 2009 at 21:10 UTC
    This is the way I like to do this. I put the input and the condition that stops the loop in the while() statement. The first snippet exits loop when a line with only white space is there. Note that \n counts as white space (\n\r\n\f\t ). The second example shows how to stop on "quit"

    The third example is more complicated and uses the "comma operator". This allows the user prompt to be part of the statement in the while()condition.

    #!/usr/bin/perl -w use strict; while ((my $line=<STDIN>) !~ /^\s*$/) { print $line; } # to stop on quit use this: while ((my $line=<STDIN>) !~ /^\s*q(uit)?\s*$/i) { } #use of comma operator #note paren's are needed around print to get #line buffering to work out right. while ((print "enterline:"), (my $line=<STDIN>) !~ /^\s*$/) { print $line; }