Why does STDIN cause my Perl program to freeze?
Asked Answered
P

4

7

I am learning Perl and wrote this script to practice using STDIN. When I run the script, it only shows the first print statement on the console. No matter what I type in, including new lines, the console doesn't show the next print statement. (I'm using ActivePerl on a Windows machine.) It looks like this:

$perl script.pl
What is the exchange rate? 90.45
[Cursor stays here]

This is my script:

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

print "What is the exchange rate? ";
my @exchangeRate = <STDIN>;
chomp(@exchangeRate);

print "What is the value you would like to convert? ";
chomp(my @otherCurrency = <STDIN>);

my @result = @otherCurrency / @exchangeRate;
print "The result is @{result}.\n";

One potential solution I noticed while researching my problem is that I could include

use IO::Handle;
and
flush STDIN; flush STDOUT;
in my script. These lines did not solve my problem, though.

What should I do to have STDIN behave normally? If this is normal behavior, what am I missing?

Polymath answered 12/10, 2010 at 20:21 Comment(0)
T
18

When you do

my @answer = <STDIN>;

...Perl waits for the EOF character (on Unix and Unix-like it's Ctrl-D). Then, each line you input (separated by linefeeds) go into the list.

If you instead do:

my $answer = <STDIN>;

...Perl waits for a linefeed, then puts the string you entered into $answer.

Tractable answered 12/10, 2010 at 20:26 Comment(2)
On UNIX and UNIX-like system the end of line character is linefeed, not carriage return.Pansophy
Thanks! I realized that I wasn't using a scalar after I made my post. >_< Thanks for pointing out how to use STDIN with an array!Polymath
P
5

I found my problem. I was using the wrong type of variable. Instead of writing:

my @exchangeRate = <STDIN>;

I should have used:

my $exchangeRate = <STDIN>;

with a $ instead of a @.

Polymath answered 12/10, 2010 at 20:33 Comment(0)
C
4

To end multiline input, you can use Control-D on Unix or Control-Z on Windows.

However, you probably just wanted a single line of input, so you should have used a scalar like other people mentioned. Learning Perl walks you through this sort of stuff.

Coworker answered 12/10, 2010 at 23:59 Comment(0)
S
-3

You could try and enable autoflush.

Either

use IO::Handle;
STDOUT->autoflush(1);

or

$| = 1;

That's why you are not seeing the output printed.

Also, you need to change from arrays '@' to scalar variables '$'

$val = <STDIN>;
chomp($val);
Slemmer answered 12/10, 2010 at 20:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.