Keyboard input/Flush the keyboard buffer: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎{{header|Ada}}: Beautified source code and output.)
(Add Seed7 example)
Line 168: Line 168:
else puts 'No line!'
else puts 'No line!'
end</lang>
end</lang>

=={{header|Seed7}}==
The Seed7 library [http://seed7.sourceforge.net/libraries/keybd.htm keybd.s7i]
defines the file [http://seed7.sourceforge.net/manual/file.htm#Keyboard_file KEYBOARD],
which provides functions like [http://seed7.sourceforge.net/libraries/keybd.htm#keypressed%28in_keyboard_file%29 keypressed]
and [http://seed7.sourceforge.net/libraries/keybd.htm#getc%28in_console_keybd_file%29 getc].

<lang seed7>while keypressed(KEYBOARD) do
ignore(getc(KEYBOARD));
end while;</lang>


=={{header|Tcl}}==
=={{header|Tcl}}==

Revision as of 12:55, 10 February 2012

Task
Keyboard input/Flush the keyboard buffer
You are encouraged to solve this task according to the task description, using any language you may know.

Flush the keyboard buffer. This reads characters from the keyboard input and discards them until there are no more currently buffered, and then allows the program to continue. The program must not wait for users to type anything.

Ada

<lang Ada>with Ada.Text_IO; procedure Flushtest is

  use Text_IO;

begin

  Put_Line ("Type anything for 2 s");
  delay 2.0;

Flush_Input:

  declare
     Ch   : Character;
     More : Boolean;
  begin
     loop
        Get_Immediate (Ch, More);
        exit when not More;
     end loop;
  end Flush_Input;
  New_Line;
  Put_Line ("Okay, thanks. Here is some input from you:");
  Put_Line (Get_Line);

end Flushtest;</lang>

BASIC

Locomotive Basic

<lang locobasic>10 CLEAR INPUT</lang>

(Only available in BASIC 1.1 though, i.e. not on the CPC 464.)

ZX Spectrum Basic

<lang basic>10 IF INKEY$ <> "" THEN GO TO 10</lang>

C

This example is untested. Please check that it's correct, debug it as necessary, and remove this message.


Library: POSIX

<lang c>#include <termios.h>

  1. include <unistd.h>

tcflush(STDIN_FILENO, TCIFLUSH);</lang>

Euphoria

<lang Euphoria>while get_key()!=-1 do end while</lang>

Icon and Unicon

The following solution works in both Icon and Unicon. <lang unicon>procedure flushKB()

   while kbhit() do getch()   # flush input

end</lang>

PicoLisp

<lang PicoLisp>(while (key 10))</lang>

PowerShell

The following uses the special $Host variable which points to an instance of the PowerShell host application. Since the host's capabilities may vary this may not work in all PowerShell hosts. In particular, this works in the console host, but not in the PowerShell ISE. <lang powershell>while ($Host.UI.RawUI.KeyAvailable) {

   $Host.UI.RawUI.ReadKey() | Out-Null

}</lang>

PureBasic

<lang PureBasic>While Inkey(): Wend</lang>

Python

<lang Python>def flush_input():

   try:
       import msvcrt
       while msvcrt.kbhit():
           msvcrt.getch()
   except ImportError:
       import sys, termios
       termios.tcflush(sys.stdin, termios.TCIOFLUSH)

</lang>

Ruby

Each terminal device has an input queue for keyboard input. We can either flush this input queue, or read it empty.

Ruby 1.9.3 adds a new library 'io/console', providing IO#iflush to flush and discard the input queue. If its IO object is not a terminal, it raises an error, perhaps Errno::ENODEV.

Works with: Ruby version 1.9.3

<lang ruby>require 'io/console' $stdin.iflush</lang>

The other option uses IO#read_nonblock to read the input, without any blocking or waiting. This has a caveat: if the terminal uses the canonical input mode, IO reads only entire lines; and if the input queue contains part of a line, IO#read_nonblock cannot discard this last partial line!

<lang ruby>loop { $stdin.read_nonblock(256) } rescue nil</lang>

The complete solution calls IO#iflush, or turns off canonical input mode and calls IO#read_nonblock.

<lang ruby>class IO

 def discard_input
   icanon = false
   if tty?
     begin
       # With Ruby 1.9.3, simply call IO#iflush.
       require 'io/console'
       return iflush
     rescue LoadError
       # Try to run stty(1) to check if this terminal uses
       # canonical input mode. Acts like `stty -a`, but redirects
       # stdin from tty. Works with Ruby 1.8, no Process#spawn.
       r, w, pid = nil
       begin
         r, w = IO.pipe
         pid = fork do
           IO.for_fd(0).reopen(self)  # stdin from tty
           IO.for_fd(1).reopen(w)     # stdout to pipe
           exec 'stty', '-a'
         end
         w.close; w = nil
         icanon = (not r.read.include? "-icanon")
       rescue
         # stty(1) only works with Unix clones.
       ensure
         pid and Process.wait pid
         w and w.close
         r and r.close
       end
     end
   end
   if icanon
     # Turn off canonical input mode.
     pid = nil
     begin
       pid = fork do
         IO.for_fd(0).reopen(self)  # stdin from tty
         exec 'stty', '-icanon'
       end
     ensure
       pid and Process.wait pid
     end
   end
   # Discard input.
   loop { $stdin.read_nonblock(256) } rescue nil
   if icanon
     # Turn on canonical input mode.
     pid = nil
     begin
       pid = fork do
         IO.for_fd(0).reopen(self)  # stdin from tty
         exec 'stty', 'icanon'
       end
     ensure
       pid and Process.wait pid
     end
   end
   nil
 end

end</lang>

<lang ruby># Demonstration: discard input, then input a line from user. puts 'Type anything for 2 seconds.' sleep 2 $stdin.discard_input print 'Enter a line? ' if line = $stdin.gets then print 'Got line. ', line else puts 'No line!' end</lang>

Seed7

The Seed7 library keybd.s7i defines the file KEYBOARD, which provides functions like keypressed and getc.

<lang seed7>while keypressed(KEYBOARD) do

 ignore(getc(KEYBOARD));

end while;</lang>

Tcl

<lang tcl># No waiting for input fconfigure stdin -blocking 0

  1. Drain the data by not saving it anywhere

read stdin

  1. Flip back into blocking mode (if necessary)

fconfigure stdin -blocking 1</lang>