Is there any way to clear the STDIN buffer in Perl? A part of my program has lengthy output (enough time for someone to enter a few characters) and after that output I ask for input, but if characters were entered during the output, they are "tacked on" to whatever is entered at the input part. Here is an example of my problem:
for(my $n = 0; $n < 70000; $n++){
print $n . "\n";
}
chomp(my $input = <STDIN>);
print $input . "\n";
The output would include any characters entered during the output from that for loop. How could I either disable STDIN or flush the STDIN buffer (or any other way to not allow extra characters to be inserted into STDIN before calling it)?
The function fflush(stdin) is used to flush or clear the output buffer of the stream. When it is used after the scanf(), it flushes the input buffer also. It returns zero if successful, otherwise returns EOF and feof error indicator is set.
If you just want to flush the Perl buffer, you can close the file, print a string containing "\n" (since it appears that Perl flushes on newlines), or use IO::Handle 's flush method. You can also, per the perl faq use binmode or play with $| to make the file handle unbuffered.
It looks like you can accomplish this with the Term::ReadKey
module:
#!perl
use strict;
use warnings;
use 5.010;
use Term::ReadKey;
say "I'm starting to sleep...";
ReadMode 2;
sleep(10);
ReadMode 3;
my $key;
while( defined( $key = ReadKey(-1) ) ) {}
ReadMode 0;
say "Enter something:";
chomp( my $input = <STDIN> );
say "You entered '$input'";
Here's what happens:
ReadMode 2
means "put the input mode into regular mode but turn off echo". This means that any keyboard banging that the user does while you're in your computationally-expensive code won't get echoed to the screen. It still gets entered into STDIN
's buffer though, so...ReadMode 3
turns STDIN
into cbreak mode, meaning STDIN
kind of gets flushed after every keypress. That's why...while(defined($key = ReadKey(-1))) {}
happens. This is flushing out the characters that the user entered during the computationally-expensive code. Then...ReadMode 0
resets STDIN
, and you can read from STDIN
as if the user hadn't banged on the keyboard.When I run this code and bang on the keyboard during the sleep(10)
, then enter some other text after the prompt, it only prints out the text I typed after the prompt appeared.
Strictly speaking the ReadMode 2
isn't needed, but I put it there so the screen doesn't get cluttered up with text when the user bangs on the keyboard.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With