Keyboard input/Flush the keyboard buffer: Difference between revisions

imported>Fth
 
(13 intermediate revisions by 8 users not shown)
Line 16:
''The program must not wait for users to type anything.''
<br><br>
=={{header|6502 Assembly}}==
{{works with|http://skilldrick.github.io/easy6502/ Easy6502}}
On the Easy6502 and 6502asm simulators, the zero page memory address 0xFF is a memory-mapped port that reflects the [[ASCII]] code of last key you pressed on your keyboard.
 
Writing a value of 0 (or almost any ASCII control code that you can't type on your keyboard) to it effectively flushes the keyboard buffer. This prevents an input loop from thinking your finger is still on that key even after you stopped pressing it.
 
<syntaxhighlight lang="6502asm">lda #$00
sta $FF</syntaxhighlight>
 
=={{header|8086 Assembly}}==
{{works with|MS-DOS}}
Depending on the value of <code>AL</code>, you can have this system call "slide" into another related system call immediately after flushing the keyboard buffer. After flushing the keyboard buffer, <code>AL</code> will be copied into <code>AH</code> and then <code>int 21h</code> will be called again. Make sure that any other parameters needed by the interrupt you "slide into" are loaded before flushing, as you won't get a chance to do so between the flush and the second system call!
 
The valid values of <code>AL</code> for this interrupt are:
* 0x01: Read a character from standard input with echo
* 0x06: Direct console output
* 0x07: Direct character input, no echo
* 0x08: Character input without echo
* 0x0A: Buffered input (for text strings).
 
 
If you just want to flush the keyboard buffer without doing anything else, load a zero (or any value that isn't one of the above) into <code>AL</code>.
 
<syntaxhighlight lang="asm">mov ax,0C00h ;equivalent of "mov ah,0Ch mov al,0"
int 21h</syntaxhighlight>
 
<syntaxhighlight lang="asm">mov ax,0C0Ah
int 21h ;flush the keyboard buffer then immediately ask the user to type in a sentence and hit Enter when done.</syntaxhighlight>
 
=={{header|AArch64 Assembly}}==
{{works with|as|Raspberry Pi 3B version Buster 64 bits}}
<syntaxhighlight lang="aarch64 assembly">
<lang AArch64 Assembly>
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program keyboardInput64.s */
Line 387 ⟶ 415:
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
</syntaxhighlight>
</lang>
{{output}}
<pre>
Line 394 ⟶ 422:
kk
End program OK.
</pre>
 
=={{header|Action!}}==
<syntaxhighlight lang="action!">PROC Wait(BYTE frames)
BYTE RTCLOK=$14
frames==+RTCLOK
WHILE frames#RTCLOK DO OD
RETURN
 
PROC Main()
BYTE CH=$02FC ;Internal hardware value for last key pressed
 
PrintE("Program is halted for 200 frames.")
PrintE("Type character to fill the buffer.")
Wait(200)
PutE()
 
DO
IF CH=$FF THEN
PrintE("The buffer is empty.")
EXIT
ELSE
PrintF("The buffer stores internal key: %B.%E",CH)
PrintE("Flush the buffer.")
CH=$FF
FI
OD
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Flush_the_keyboard_buffer.png Screenshot from Atari 8-bit computer]
<pre>
Program is halted for 200 frames.
Type character to fill the buffer.
 
The buffer stores internal key: 63.
Flush the buffer.
The buffer is empty.
</pre>
 
=={{header|Ada}}==
 
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO;
procedure Flushtest is
use Text_IO;
Line 417 ⟶ 482:
Put_Line ("Okay, thanks. Here is some input from you:");
Put_Line (Get_Line);
end Flushtest;</langsyntaxhighlight>
 
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi}}
<syntaxhighlight lang="arm assembly">
<lang ARM Assembly>
/* Programme assembleur ARM Raspberry */
/* modèle B 512MO */
Line 729 ⟶ 795:
/***************************************************/
.include "../affichage.inc"
</syntaxhighlight>
</lang>
=={{header|AWK}}==
<syntaxhighlight lang="awk">
<lang AWK>
# syntax: TAWK -f KEYBOARD_INPUT_FLUSH_THE_KEYBOARD_BUFFER.AWK
BEGIN {
Line 739 ⟶ 805:
exit(0)
}
</syntaxhighlight>
</lang>
 
=={{header|Axe}}==
<langsyntaxhighlight lang="axe">While getKey(0)
End</langsyntaxhighlight>
 
=={{header|Bash}}==
Line 749 ⟶ 815:
The <code>-t 0</code> should theoretically work, but it does not seem to for tests that have been tried in cygwin and FreeBSD.
 
<langsyntaxhighlight lang="bash">while read -t 0.01; do
true
done</langsyntaxhighlight>
 
=={{header|BASIC}}==
 
==={{header|Applesoft BASIC}}===
<langsyntaxhighlight ApplesoftBasiclang="applesoftbasic">10 IF PEEK (49152) > 127 THEN C = PEEK (49168): GOTO 10</langsyntaxhighlight>
 
==={{header|BASIC256}}===
<syntaxhighlight lang="freebasic">while key <> "" : end while
print "Keyboard buffer flushed"</syntaxhighlight>
 
==={{header|Commodore BASIC}}===
Line 762 ⟶ 832:
GET will fetch a single byte from the keyboard buffer, if one is present. The keyboard buffer will hold up to ten bytes before ignoring additional input.
 
<langsyntaxhighlight lang="coomodorebasicv2">10 print chr$(147);chr$(14)
25 get k$:if k$<>"" then 25:rem empty buffer
40 print chr$(19):print " Program halted for 10000 counts. "
Line 772 ⟶ 842:
75 if k$<>"" then 65
80 print
85 end</langsyntaxhighlight>
 
{{out}}
Line 789 ⟶ 859:
==={{header|Locomotive Basic}}===
 
<syntaxhighlight lang ="locobasic">10 CLEAR INPUT</langsyntaxhighlight>
 
(Only available in BASIC 1.1 though, i.e. not on the CPC 464.)
 
==={{header|QBasic}}===
{{works with|QBasic|1.1}}
{{works with|QuickBasic|4.5}}
{{works with|True BASIC}}
<syntaxhighlight lang="qbasic">DO WHILE INKEY$ <> ""
LOOP
PRINT "Keyboard buffer flushed"
END</syntaxhighlight>
 
==={{header|Run BASIC}}===
{{works with|QBasic}}
{{works with|FreeBASIC}}
<syntaxhighlight lang="runbasic">while inkey$ <> "" : wend
print "Keyboard buffer flushed"</syntaxhighlight>
 
==={{header|True BASIC}}===
{{works with|QBasic}}
<syntaxhighlight lang="qbasic">DO WHILE INKEY$ <> ""
LOOP
PRINT "Keyboard buffer flushed"
END</syntaxhighlight>
 
==={{header|ZX Spectrum Basic}}===
Line 797 ⟶ 889:
There is no need to flush keyboard buffer in Spectrum since key presses are not buffered.
If a key is currently pressed, the following waits until key is released.
<langsyntaxhighlight lang="basic">10 IF INKEY$ <> "" THEN GO TO 10</langsyntaxhighlight>
 
=={{header|BBC BASIC}}==
<langsyntaxhighlight lang="bbcbasic"> *FX 15,1</langsyntaxhighlight>
Strictly speaking *FX 15,1 is an Operating System command, but it is emulated in BBC BASIC for Windows. Alternatively the keyboard buffer may be flushed as follows:
<langsyntaxhighlight lang="bbcbasic"> REPEAT UNTIL INKEY(0)=-1</langsyntaxhighlight>
or:
<langsyntaxhighlight lang="bbcbasic"> REPEAT UNTIL INKEY$(0)=""</langsyntaxhighlight>
 
=={{header|C}}==
===Simple solution for stdin===
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
 
Line 823 ⟶ 915:
// fflush(stdin);
 
// Always works. TheReaded onlycharacters differencemay isremain (?)somethere thatin readed characters mayRAM.
// remain somethere in RAM.
//
fseek(stdin, 0, SEEK_END);
 
// BTW, aA very dirty solution is below - an unbuffered stream does not need any flushing.
// any flushing etc. It should be safe - i.e. if called before any I/O then
// no trace of buffered characters remain in RAM. Use with care.
//
// setvbuf(stdin, NULL, _IONBF, 0);
 
// Now we are able to check if the buffer is really empty.
// BTW, NEVER use gets due to possible the buffer overrun.
//
fgets(text, sizeof(text), stdin);
Line 841 ⟶ 929:
 
return EXIT_SUCCESS;
}</langsyntaxhighlight>
 
===POSIX===
{{libheader|POSIX}}
Code lifted from [[Keyboard input/Obtain a Y or N response]]:
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdio.h>
#include <termios.h>
Line 913 ⟶ 1,001:
 
return 0;
}</langsyntaxhighlight>
===Solution for MSVC conio===
 
{{libheader|Windows MSVC}}
<langsyntaxhighlight lang="c">#include <conio.h>
#include <tchar.h>
 
Line 938 ⟶ 1,026:
Kbflush();
return 0;
}</langsyntaxhighlight>
 
=={{header|D}}==
<langsyntaxhighlight lang="d">extern (C) {
void _STI_conio();
void _STD_conio();
Line 958 ⟶ 1,046:
 
_STD_conio();
}</langsyntaxhighlight>
 
=={{header|DCL}}==
<syntaxhighlight lang="text">$ wait 0::10 ! gives us 10 seconds to get keystrokes into the type-ahead buffer
$ on control_y then $ goto clean
$ set terminal /noecho
Line 967 ⟶ 1,055:
$ goto loop
$ clean:
$ set terminal /echo</langsyntaxhighlight>
{{out}}
<pre>$ @flush_the_keyboard_buffer ! ignores/discards keystrokes for 10 seconds
$</pre>
=={{header|Delphi}}==
{{libheader| Winapi.Windows}}
<syntaxhighlight lang="delphi">
program Flush_the_keyboard_buffer;
 
{$APPTYPE CONSOLE}
 
uses
Winapi.Windows;
 
var
StdIn: THandle;
 
begin
StdIn := GetStdHandle(STD_INPUT_HANDLE);
Writeln('Press any key you want, they will be erased:');
Sleep(5000);
FlushConsoleInputBuffer(StdIn);
Writeln('Now press any key you want, they will NOT be erased:');
readln;
end.</syntaxhighlight>
=={{header|ERRE}}==
<syntaxhighlight lang="erre">
<lang ERRE>
!$KEY
..........
Line 980 ⟶ 1,088:
UNTIL K$=""
..........
</syntaxhighlight>
</lang>
Note: Test after K$ can be replaced with <code>LEN(K$)=0</code>.
 
=={{header|Euphoria}}==
<langsyntaxhighlight Euphorialang="euphoria">while get_key()!=-1 do
end while</langsyntaxhighlight>
 
=={{header|Forth}}==
<syntaxhighlight lang="forth">
: flush-keys begin key? while key drop repeat ;
</syntaxhighlight>
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang="freebasic">' FB 1.05.0 Win64
 
' Get characters from the keyboard buffer until there are none left
While Inkey <> "" : Wend
Print "Keyboard buffer flushed"
Sleep</langsyntaxhighlight>
 
=={{header|Go}}==
{{libheader|Curses}}
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,012 ⟶ 1,124:
defer gc.End()
gc.FlushInput()
}</langsyntaxhighlight>
::<langsyntaxhighlight lang="go">package main
 
import (
Line 1,047 ⟶ 1,159:
}
}
</syntaxhighlight>
</lang>
 
=={{header|Haskell}}==
This relies upon POSIX terminal support.
<langsyntaxhighlight lang="haskell">import Control.Concurrent (threadDelay)
import Control.Monad (when)
import System.IO (hFlush, stdout)
Line 1,076 ⟶ 1,188:
line <- getLine
putStrLn $ "You typed: " ++ line
termFlush stdInput</langsyntaxhighlight>
 
=={{header|i}}==
Line 1,083 ⟶ 1,195:
=={{header|Icon}} and {{header|Unicon}}==
The following solution works in both Icon and Unicon.
<langsyntaxhighlight lang="unicon">procedure flushKB()
while kbhit() do getch() # flush input
end</langsyntaxhighlight>
 
=={{header|Julia}}==
{{libheader|Gtk}}
<langsyntaxhighlight lang="julia">
using Gtk
 
Line 1,099 ⟶ 1,211:
sleep(0.25)
end
</syntaxhighlight>
</lang>
 
=={{header|Kotlin}}==
There appears to be no completely satisfactory, platform independent, way in Java (and hence in the JVM-targetted version of Kotlin) to flush the keyboard buffer. The method presented here may not always work (as the InputStream.available method only gives an estimate of the bytes in the buffer) but is better than nothing and does not block as other approaches to the problem may do.
<langsyntaxhighlight lang="scala">// version 1.0.6
 
fun main(args: Array<String>) {
while (System.`in`.available() > 0) System.`in`.read()
println("Goodbye!")
}</langsyntaxhighlight>
 
=={{header|M2000 Interpreter}}==
Line 1,122 ⟶ 1,234:
 
 
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module Checkit {
\\ feed keyboard
Line 1,139 ⟶ 1,251:
}
Checkit
</syntaxhighlight>
</lang>
 
This isn't the task. Input ends when statement Input End occur, in a thread.
Line 1,146 ⟶ 1,258:
 
 
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module checkit {
Print "You have 3 seconds to write your name (press enter)"
Line 1,157 ⟶ 1,269:
}
Checkit
</syntaxhighlight>
</lang>
 
=={{header|MiniScript}}==
{{works with|Mini Micro}}
<syntaxhighlight lang MiniScript="miniscript">key.clear</langsyntaxhighlight>
 
=={{header|Nim}}==
{{libheader|POSIX}}
<langsyntaxhighlight lang="nim">const TCIFLUSH: cint = 0
proc tcflush(fd, queue_selector: cint): cint {.header: "termios.h".}
 
discard tcflush(cint(getFileHandle(stdin)), TCIFLUSH)</langsyntaxhighlight>
 
=={{header|Oforth}}==
 
<langsyntaxhighlight Oforthlang="oforth">import: console
 
System.Console flush</langsyntaxhighlight>
 
=={{header|Perl}}==
 
<langsyntaxhighlight lang="perl">use Term::ReadKey;
ReadMode 'restore'; # Flush the keyboard and returns input stream to initial state
# ReadMode 0; # Numerical equivalent of keyboard restore (move comment marker to use instead)
Line 1,194 ⟶ 1,306:
 
# Don't forget to restore the readmode, when we are finished using the keyboard
ReadMode 'restore';</langsyntaxhighlight>
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">-->
<lang Phix>while get_key()!=-1 do end while</lang>
<span style="color: #008080;">while</span> <span style="color: #7060A8;">get_key</span><span style="color: #0000FF;">()!=-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span> <span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<!--</syntaxhighlight>-->
 
=={{header|PicoLisp}}==
<syntaxhighlight lang PicoLisp="picolisp">(while (key 10))</langsyntaxhighlight>
 
=={{header|PowerShell}}==
The following uses the special <code>$Host</code> 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.
<langsyntaxhighlight lang="powershell">while ($Host.UI.RawUI.KeyAvailable) {
$Host.UI.RawUI.ReadKey() | Out-Null
}</langsyntaxhighlight>
 
To flush the keyboard buffer use:
<langsyntaxhighlight lang="powershell">
$Host.UI.RawUI.FlushInputBuffer()
</syntaxhighlight>
</lang>
 
=={{header|PureBasic}}==
<syntaxhighlight lang PureBasic="purebasic">While Inkey(): Wend</langsyntaxhighlight>
 
=={{header|Python}}==
<langsyntaxhighlight Pythonlang="python">def flush_input():
try:
import msvcrt
Line 1,225 ⟶ 1,339:
import sys, termios
termios.tcflush(sys.stdin, termios.TCIOFLUSH)
</syntaxhighlight>
</lang>
 
=={{header|Racket}}==
Line 1,231 ⟶ 1,345:
Using <tt>stty</tt> to get the terminal into raw mode.
 
<langsyntaxhighlight lang="racket">
#lang racket
(define-syntax-rule (with-raw body ...)
Line 1,247 ⟶ 1,361:
(printf "Now press a key which will not be ignored\n")
(printf "You pressed ~a\n" (read-char)))
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
Line 1,253 ⟶ 1,367:
{{works with|Rakudo|2018.12}}
Using termios to set some input attributes, flush the buffer & do unbuffered reads. Longer than strictly necessary to demonstrate concepts and make it easy to verify that it actually works as advertised.
<syntaxhighlight lang="raku" perl6line>use Term::termios;
 
constant $saved = Term::termios.new( :fd($*IN.native-descriptor) ).getattr;
Line 1,286 ⟶ 1,400:
print $keypress.decode.ords;
print "|";
}</langsyntaxhighlight>
 
=={{header|REXX}}==
This will work for Regina:
<syntaxhighlight lang ="rexx">call dropbuf</langsyntaxhighlight>
This will work for CMS REXX, PC/REXX, Personal REXX, and TSO REXX:
<syntaxhighlight lang ="rexx">'DROPBUF'</langsyntaxhighlight>
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
# Project: Keyboard input/Flush the keyboard buffer
 
Fflush(stdin)
</syntaxhighlight>
</lang>
 
=={{header|Ruby}}==
Line 1,307 ⟶ 1,421:
 
{{works with|Ruby|1.9.3}}
<langsyntaxhighlight lang="ruby">require 'io/console'
$stdin.iflush</langsyntaxhighlight>
 
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!
 
<langsyntaxhighlight lang="ruby">loop { $stdin.read_nonblock(256) } rescue nil</langsyntaxhighlight>
 
The complete solution calls IO#iflush, or turns off canonical input mode and calls IO#read_nonblock.
 
<langsyntaxhighlight lang="ruby">class IO
def discard_input
icanon = false
Line 1,379 ⟶ 1,493:
nil
end
end</langsyntaxhighlight>
 
<langsyntaxhighlight lang="ruby"># Demonstration: discard input, then input a line from user.
puts 'Type anything for 2 seconds.'
sleep 2
Line 1,389 ⟶ 1,503:
then print 'Got line. ', line
else puts 'No line!'
end</langsyntaxhighlight>
 
=={{header|Scala}}==
<langsyntaxhighlight lang="scala">def flush() { out.flush() }</langsyntaxhighlight>
 
=={{header|Seed7}}==
Line 1,400 ⟶ 1,514:
and [http://seed7.sourceforge.net/libraries/keybd.htm#getc%28in_console_keybd_file%29 getc].
 
<langsyntaxhighlight lang="seed7">while keypressed(KEYBOARD) do
ignore(getc(KEYBOARD));
end while;</langsyntaxhighlight>
 
=={{header|Sidef}}==
{{trans|Perl}}
<langsyntaxhighlight lang="ruby">var k = frequire('Term::ReadKey');
 
k.ReadMode('restore'); # Flush the keyboard and returns input stream to initial state
Line 1,422 ⟶ 1,536:
 
# Don't forget to restore the readmode, when we are finished using the keyboard
k.ReadMode('restore');</langsyntaxhighlight>
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl"># No waiting for input
fconfigure stdin -blocking 0
# Drain the data by not saving it anywhere
Line 1,431 ⟶ 1,545:
 
# Flip back into blocking mode (if necessary)
fconfigure stdin -blocking 1</langsyntaxhighlight>
 
=={{header|Vedit macro language}}==
<syntaxhighlight lang ="vedit">Key_Purge()</langsyntaxhighlight>
 
=={{header|Wren}}==
There is currently no direct way to flush the keyboard buffer from Wren-cli.
 
However, the ''System.readByte()'' method reads and removes the next byte from the buffer, blocking the fiber until ''enter'' is pressed. Consequently, the following code will only flush the buffer if ''enter'' is the last key pressed.
 
It is necessary to type in some keys first (and have them echoed) to demonstrate that it is in fact working. 'Raw' mode can't be used here as keyboard input is not buffered in that mode.
<syntaxhighlight lang="wren">import "io" for Stdin
 
System.print("Press some keys followed by enter.")
while (true) {
var b = Stdin.readByte() // reads and removes a key from the buffer
System.print("Removed key with code %(b).")
if (b == 10) break // buffer will be empty when enter key pressed
}
System.print("Keyboard buffer is now empty.")</syntaxhighlight>
 
{{out}}
Sample session when the keys a, b, c, d followed by enter are pressed:
<pre>
Press some keys followed by enter.
abcd
Removed key with code 97.
Removed key with code 98.
Removed key with code 99.
Removed key with code 100.
Removed key with code 10.
Keyboard buffer is now empty.
</pre>
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="xpl0">code OpenI=13;
OpenI(0)</langsyntaxhighlight>
Anonymous user