mcwillig mcwillig - 4 months ago 15
Perl Question

Flushing Perl STDIN buffer

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)?


It looks like you can accomplish this with the Term::ReadKey module:


use strict;
use warnings;
use 5.010;

use Term::ReadKey;

say "I'm starting to sleep...";
ReadMode 2;
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.