Keyboard input/Obtain a Y or N response

From Rosetta Code
Jump to: navigation, search
Task
Keyboard input/Obtain a Y or N response
You are encouraged to solve this task according to the task description, using any language you may know.

Obtain a valid Y or N response from the keyboard. The keyboard should be flushed, so that any outstanding keypresses are removed, preventing any existing Y or N keypress from being evaluated. The response should be obtained as soon as Y or N are pressed, and there should be no need to press an enter key.

Contents

[edit] Ada

   function Yes_Or_No (Prompt : String := "Your answer (Y/N): ") return Boolean is
Answer : Character;
begin
Ada.Text_IO.Put (Prompt);
loop
Ada.Text_IO.Get_Immediate (Answer);
case Answer is
when 'Y'|'y' => return True;
when 'N'|'n' => return False;
when others => null;
end case;
end loop;
end Yes_Or_No;

[edit] AutoHotkey

Loop, {
Input, Key, L1
if (Key = "n" || Key = "y")
break
}
MsgBox, % "The response was """ Key """."
ExitApp

[edit] AWK

 
# syntax: GAWK -f KEYBOARD_INPUT_OBTAIN_A_Y_OR_N_RESPONSE.AWK
BEGIN {
printf("you entered %s\n",prompt_user())
exit(0)
}
function prompt_user( rec) {
# AWK lacks the ability to get keyboard input without pressing the enter key.
while (1) {
printf("enter Y or N ")
getline rec <"con"
gsub(/ /,"",rec) # optional
if (rec ~ /^[nyNY]$/) {
break
}
}
return(rec)
}
 
Output:
enter Y or N y
you entered y

[edit] BASIC

[edit] Applesoft BASIC

10  LET C =  PEEK (49168): REM CLEAR KEYBOARD
20 PRINT "PRESS Y OR N TO CONTINUE"
30 GET K$
40 IF K$ < > "Y" AND K$ < > "N" THEN 30
50 PRINT "THE RESPONSE WAS ";K$
 

[edit] Locomotive Basic

10 CLEAR INPUT
20 PRINT "Press Y or N to continue"
30 a$=LOWER$(INKEY$)
40 IF a$="" THEN 30
50 IF a$="y" THEN PRINT "Yes":END
60 IF a$="n" THEN PRINT "No":END
70 PRINT "Try again"
80 GOTO 30

[edit] ZX Spectrum Basic

Note that this will also work in GW-BASIC and most QBasic-compatible BASICs if all instances of "GO TO" are changed to "GOTO".

10 IF INKEY$<>"" THEN GO TO 10: REM flush the keyboard buffer
20 PRINT "Press Y or N to continue"
30 LET k$ = INKEY$
40 IF k$ <> "y" AND k$ <> "Y" AND k$ <> "n" AND k$ <> "N" THEN GO TO 30
50 PRINT "The response was "; k$

[edit] BBC BASIC

      REPEAT UNTIL INKEY$(0) = ""
PRINT "Press Y or N to continue"
REPEAT
key$ = GET$
UNTIL key$="Y" OR key$="N"
PRINT "The response was " key$

[edit] Commodore BASIC

10 PRINT "PRESS Y OR N TO CONTINUE:";
20 POKE 198, 0: REM CLEAR KEY BUFFER
30 GET K$
40 IF K$ <> "Y" AND K$ <> "N" THEN 30
50 PRINT K$

Note that 198 is the location of the keyboard buffer index on the VIC-20, C-64, and C-128. On the PET, the correct location is 158, while on the Plus/4 and C-16, it's 239.

The loop on lines 30 - 40 will cycle as fast as the interpreter can go, assigning K$ the empty string until the user presses a key. On versions of BASIC later than the 2.0 on the VIC and 64 (e.g. 3.5 on the C-16 and Plus/4, 7.0 on the C-128), GETKEY may be used in place of GET. GETKEY will wait for the user to press a key before continuing, so the polling is done in the BASIC interpreter's machine language code, and the BASIC loop only cycles when the user presses a key other than Y or N.

[edit] Batch File

 
@echo off
choice
if errorlevel 2 echo You chose N
if errorlevel 1 echo You chose Y
>nul pause
 

[edit] C

For POSIX compliant systems (in theory that includes WinNT family).

#include <stdio.h>
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
 
void set_mode(int want_key)
{
static struct termios old, new;
if (!want_key) {
tcsetattr(STDIN_FILENO, TCSANOW, &old);
return;
}
 
tcgetattr(STDIN_FILENO, &old);
new = old;
new.c_lflag &= ~(ICANON);
tcsetattr(STDIN_FILENO, TCSANOW, &new);
}
 
int get_key(int no_timeout)
{
int c = 0;
struct timeval tv;
fd_set fs;
tv.tv_usec = tv.tv_sec = 0;
 
FD_ZERO(&fs);
FD_SET(STDIN_FILENO, &fs);
 
select(STDIN_FILENO + 1, &fs, 0, 0, no_timeout ? 0 : &tv);
if (FD_ISSET(STDIN_FILENO, &fs)) {
c = getchar();
set_mode(0);
}
return c;
}
 
int main()
{
int c;
while(1) {
set_mode(1);
while (get_key(0)); /* clear buffer */
printf("Prompt again [Y/N]? ");
fflush(stdout);
 
c = get_key(1);
if (c == 'Y' || c == 'y') {
printf("\n");
continue;
}
 
if (c == 'N' || c == 'n') {
printf("\nDone\n");
break;
}
 
printf("\nYes or no?\n");
}
 
return 0;
}

[edit] C#

using System;
 
namespace Y_or_N
{
class Program
{
static void Main()
{
bool response = GetYorN();
}
 
static bool GetYorN()
{
ConsoleKey response; // Creates a variable to hold the user's response.
 
do
{
while (Console.KeyAvailable) // Flushes the input queue.
Console.ReadKey();
 
Console.Write("Y or N? "); // Asks the user to answer with 'Y' or 'N'.
response = Console.ReadKey().Key; // Gets the user's response.
Console.WriteLine(); // Breaks the line.
} while (response != ConsoleKey.Y && response != ConsoleKey.N); // If the user did not respond with a 'Y' or an 'N', repeat the loop.
 
/*
* Return true if the user responded with 'Y', otherwise false.
*
* We know the response was either 'Y' or 'N', so we can assume
* the response is 'N' if it is not 'Y'.
*/

return response == ConsoleKey.Y;
}
}
}

[edit] Common Lisp

 
(defun y-or-n ()
(clear-input *standard-input*)
(loop as dum = (format t "Y or N for yes or no: ")
as c = (read-char)
as q = (and (not (equal c #\n)) (not (equal c #\y)))
when q do (format t "~%Need Y or N~%")
unless q return (if (equal c #\y) 'yes 'no)))
 

Better, previous version:

 
(defun rosetta-y-or-n ()
(clear-input *query-io*)
(y-or-n-p))
 

Explanation:

When a single-character input is not accepted till <Enter> it means your connection to Lisp
is not direct, and whatever is doing your connection has a bug that makes it not send the input
till it has a whole line to send.  Both of the above versions work fine in Lispworks, and respond
immediately to a single character.  To fix a bug that requires <Enter> when it shouldn't, fix
that in the configuration of whatever sends your input to Lisp.  The main difference in the above
two versions is that the long one uses *STANDARD-INPUT* instead of *QUERY_IO* which might or might
not make a difference when there is a bug in your connection to your Lisp environment.

[edit] D

import std.stdio: stdout, write, writefln;
 
extern (C) nothrow {
void _STI_conio();
void _STD_conio();
int kbhit();
int getch();
}
 
void main() {
_STI_conio();
write("Enter Y or N: ");
stdout.flush();
 
int c;
do {
while(!kbhit()) {}
c = getch();
 
// Visual feedback for each keypress.
write(cast(char)c);
stdout.flush();
} while(c != 'Y' && c != 'y' && c != 'N' && c != 'n');
 
writefln("\nResponse: %c", cast(char)c);
_STD_conio();
}
Output:
Enter Y or N: abcN
Response: N


[edit] ERRE

 
!$KEY
................
! flush the keyboard buffer
REPEAT
GET(K$)
UNTIL K$=""
 
PRINT("Press Y or N to continue")
GET(K$)
UNTIL INSTR("YyNn",K$)<>0
 
PRINT("The response was ";K$)
.................
 

!$KEY is a directive pragma: using it GET become an equivalent to Qbasic INKEY$, otherwise it's equivalent to QBasic INPUT$(1). !$KEY is also used to mantain portability with the C-64 version of ERRE language.

[edit] Euphoria

integer key
 
puts(1,"Your answer? (Y/N)\n")
while get_key()!=-1 do
end while
 
while 1 do
key = get_key()
if key!=-1 and (key = 'Y' or key = 'y' or key = 'N' or key = 'n') then
exit
end if
end while
 
printf(1,"Your response was %s\n",key)

[edit] EGL

Works with: EDT
Works with: RBD
handler YesOrNoHandler type RUIhandler{initialUI =[ui], onConstructionFunction = start}
 
ui Div { };
 
const KEY_N int = 78;
const KEY_Y int = 89;
 
function start()
document.onKeyDown = d_onKeyDown;
end
 
function d_onKeyDown(e Event in)
 
case (e.ch)
when (KEY_N)
ui.innerText = "N pressed.";
when (KEY_Y)
ui.innerText = "Y pressed.";
end
 
e.preventDefault();
 
end
 
end


[edit] F#

open System
 
let rec yorn () =
let rec flush () = if Console.KeyAvailable then ignore (Console.ReadKey()); flush ()
flush ()
 
printf "\nY or N? "
match Console.ReadKey().Key with
| ConsoleKey.Y -> 'Y'
| ConsoleKey.N -> 'N'
| _ -> yorn()
 
printfn "\nYour choice: %c" (yorn())

[edit] Forth

: flush ( -- )  \ discard pending input
begin key? while key drop repeat ;
 
: y-or-n ( c-addr u -- f )
flush begin
cr 2dup type key bl or \ note 1.
dup [char] y = swap [char] n = over or \ note 2.
if nip nip exit then
drop again ;
 
\ Note 1. KEY BL OR returns a lowercase letter in the case that an
\ uppercase letter was entered, an unchanged lowercase letter in the
\ case that a lowercase letter was entered, and garbage otherwise. BL
\ returns the ASCII code for a space, 32, which is incidentally the
\ "bit of difference" between ASCII uppercase and lowercase letters.
 
\ Note 2. this line has the stack effect ( x -- f1 f2 ), where F1 is
\ true only if x='y', and F2 is true only if x='y' OR if x='n'.
 
\ I think these expressions aren't too clever, but they _are_ rather
\ optimized for the task at hand. This might be more conventional:
 
: y-or-n ( c-addr u -- f )
flush begin
cr 2dup type key case
[char] y of 2drop true exit endof
[char] Y of 2drop true exit endof
[char] n of 2drop false exit endof
[char] N of 2drop false exit endof
endcase again ;

[edit] Go

Library: Curses
package main
 
import (
"log"
 
gc "code.google.com/p/goncurses"
)
 
func main() {
s, err := gc.Init()
if err != nil {
log.Fatal("init:", err)
}
defer gc.End()
var k gc.Key
for {
gc.FlushInput()
s.MovePrint(20, 0, "Press y/n ")
s.Refresh()
switch k = s.GetChar(); k {
default:
continue
case 'y', 'Y', 'n', 'N':
}
break
}
s.Printf("\nThanks for the %c!\n", k)
s.Refresh()
s.GetChar()
}

[edit] GW-BASIC

10 IF INKEY$<>"" THEN GOTO 10: REM flush the keyboard buffer
20 PRINT "Press Y or N to continue"
30 LET k$ = INKEY$
40 IF k$ <> "y" AND k$ <> "Y" AND k$ <> "n" AND k$ <> "N" THEN GOTO 30
50 PRINT "The response was "; k$

[edit] Haskell

This may not be very idiomatic; it's pretty monad-oriented, and the use of do expressions makes the whole thing feel rather imperative.

import System.IO
 
hFlushInput :: Handle -> IO ()
hFlushInput hdl = do
r <- hReady hdl
if r then do
c <- hGetChar hdl
hFlushInput hdl
else
return ()
 
yorn :: IO Char
yorn = do
c <- getChar
if c == 'Y' || c == 'N' then return c
else if c == 'y' then return 'Y'
else if c == 'n' then return 'N'
else yorn
 
main :: IO ()
main = do
hSetBuffering stdout NoBuffering
putStr "Press Y or N to continue: "
 
hSetBuffering stdin NoBuffering
hSetEcho stdin False
hFlushInput stdin
answer <- yorn
putStrLn [answer]

[edit] Icon and Unicon

This solution works in both Icon and Unicon. It also accepts y or n.

procedure main()
write("Response was ",getResponse("OK? (Y or N): "))
end
 
procedure getResponse(prompt)
while kbhit() do getch() # flush input
writes(prompt)
repeat if map(answer := getch()) == ("y"|"n") then break
return answer
end

[edit] Inform 7

Keyboard input goes through a virtual machine that's only required to provide blocking input operations, so flushing the buffer isn't possible.

Inform 7 has a built-in function to ask the user for yes-or-no input, but it requires them to press enter afterward:

Qwantz is a room.
 
When play begins:
say "A wizard has turned you into a whale. Is this awesome (Y/N)? ";
if the player consents, say "Awesome!";
end the story.

To read a single key without waiting for enter, we can redefine the function by including a snippet of Inform 6 code:

To decide whether player consents: (- (YesOrNoKey()) -).
 
Include (-
[ YesOrNoKey ch;
do { ch = VM_KeyChar(); } until (ch == 'y' or 'Y' or 'n' or 'N');
return ch == 'y' or 'Y';
]; -).

[edit] JavaScript

Here's how you can asynchronously read a single character in Node.js, using the keypress package.

var keypress = require('keypress');
 
keypress(process.stdin);
 
process.stdin.on('keypress', function (ch, key) {
if (key && (key.name === 'y' || key.name === 'n')) {
var reply = key.name === 'y';
console.log('Reply:', reply);
// ...do something with 'reply'...
}
});
 
process.stdin.setRawMode(true);
process.stdin.resume();

This does not seem to be possible to do synchronously in Node.js or at all in the SpiderMonkey shell.

[edit] Liberty BASIC

 
nomainwin
open "Y/N" for graphics_nsb_nf as #1
#1 "trapclose Quit"
#1 "down;setfocus;when characterInput KeyCheck"
#1 "place 10 50;\Press Y or N"
Inkey$=""
wait
 
sub KeyCheck hndle$,k$
k$=upper$(k$)
#hndle$ "cls;place 10 50"
select case k$
case "Y"
#hndle$ "\ Yes"
case "N"
#hndle$ "\No"
case else
#hndle$ "\Incorrect input. Press Y or N"
end select
end sub
 
sub Quit hndle$
close #hndle$
end
end sub
 

[edit]

to yorn
type [Press Y or N to continue: ]
local "clear
make "clear readchars 0 ; clear input buffer
local "yorn
do.until [make "yorn readchar] [or equal? :yorn "Y equal? :yorn "N]
print :yorn
output :yorn
end

[edit] OpenEdge/Progress

DEF VAR lanswer AS LOGICAL INITIAL ?.
 
DO WHILE lanswer = ?:
READKEY.
IF CHR( LASTKEY ) = "n" OR CHR( LASTKEY ) = "y" THEN
lanswer = CHR( LASTKEY ) = "y".
END.
 
MESSAGE lanswer VIEW-AS ALERT-BOX.

[edit] PARI/GP

GP's input is not able to read an unbuffered single character, so one must use PARI where the solution is identical to that of C.

[edit] Pascal

Works with: Free_Pascal
Library: CRT
Program ObtainYN;
 
uses
crt;
 
var
key: char;
 
begin
write('Your answer? (Y/N): ');
repeat
key := readkey;
until (key in ['Y', 'y', 'N', 'n']);
writeln;
writeln ('Your answer was: ', key);
end.

Output:

% ./ObtainYN
Your answer? (Y/N): 
Your answer was: y

[edit] NetRexx

/* NetRexx */
 
options replace format comments java crossref savelog symbols binary
 
Say 'Please enter Y or N'
parse ask c
Select
when c='Y' Then Say 'YES'
when c='N' Then Say 'NO'
otherwise Say 'Undecided'
End

[edit] Perl

use Term::ReadKey;
 
ReadMode 4; # change to raw input mode
 
my $key = '';
 
while($key !~ /(Y|N)/i) {
1 while defined ReadKey -1; # discard any previous input
print "Type Y/N: ";
$key = ReadKey 0; # read a single character
print "$key\n";
}
 
ReadMode 0; # reset the terminal to normal mode
 
print "\nYou typed: $key\n";
 

[edit] Perl 6

my $TTY = open("/dev/tty");
 
sub prompt-char($prompt) {
ENTER shell "stty raw -echo min 1 time 1";
LEAVE shell "stty sane";
 
print $prompt;
$TTY.getc;
}
 
say so prompt-char("Y or N? ") ~~ /:i y/;

[edit] PicoLisp

(de yesno ()
(loop
(NIL (uppc (key)))
(T (= "Y" @) T)
(T (= "N" @)) ) )

[edit] PL/I

 yn: Proc Options(main):
Dcl sysin stream input;
Dcl sysprint stream output;
Dcl c Char(1);
Put Skip List('Please enter Y or N');
Get Edit(c)(a(1));
Select(c);
When('Y','y','J','j')
Put Skip List('YES');
When('N','n')
Put Skip List('NO');
Otherwise
Put Skip List('Undecided?');
End;
End;

[edit] PureBasic

Inkey() returns the character string of the key which is being pressed at the time.

PrintN("Press Y or N to continue")
 
Repeat
; Get the key being pressed, or a empty string.
Key$=UCase(Inkey())
;
; To Reduce the problems with an active loop
; a Delay(1) will release the CPU for the rest
; of this quanta if no key where pressed.
Delay(1)
Until Key$="Y" Or Key$="N"
PrintN("The response was "+Key$)

[edit] Python

#!/usr/bin/env python
 
try:
from msvcrt import getch
except ImportError:
def getch():
import sys, tty, termios
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
 
print "Press Y or N to continue"
while True:
char = getch()
if char.lower() in ("y", "n"):
print char
break

[edit] Racket

 
#lang racket
 
;; GUI version
(require racket/gui)
(message-box "Yes/No example" "Yes or no?" #f '(yes-no))
 
;; Text version, via stty
(define stty
(let ([exe (find-executable-path "stty")])
(λ args (void (apply system* exe args)))))
(define tty-settings (string-trim (with-output-to-string (λ() (stty "-g")))))
(printf "Yes or no? ") (flush-output)
(stty "-icanon" "-echo" "min" "1")
(let loop () (when (char-ready?) (loop)))
(let loop ()
(define ch (read-char))
(case (char-downcase ch)
[(#\y #\Y #\n #\N) (displayln ch) (if (memq ch '(#\y #\Y)) 'yes 'no)]
[else (loop)]))
(stty tty-settings)
 

[edit] Retro

 
 : y|n ( -c )
"\nPress Y or N..." puts
0 [ drop getc dup [ 'Y <> ] [ 'N <> ] bi and ] while cr ;
 

[edit] REXX

[edit] version for all classic REXXes

This version works with all classic REXXes.

REXX (in general) requires the user to press the   ENTER   key after entering text.
This is because the original (IBM) REXX was designed and written for a system when all I/O to a user's terminal screen was
in block mode and required the user to press one of the following before any data was sent to the computer:

  • the   ENTER   key
  • a   PF     (program function key)
  • a   PA     (program assist key)
  • the   ATTN     (attention) key
  • possibly some other special key(s)


Note that the above keys may have different names on terminals that emulate an IBM 3270 type terminal (block mode terminals).
Some older Classic REXX interpreters have a keyboard read subroutine (BIF) so that the program can read keyboard keys as
they are pressed   (see the other versions below).

/*REXX program tests for a   Y  or  N   key when entered after a prompt.*/
 
do queued(); pull; end /*flush stack if anything queued. */
 
prompt = 'Please enter Y or N for verification:' /*PROMPT msg.*/
 
do until pos(ans,'NY')\==0 & length(ans)==1 /*··· Y | N ?*/
say; say prompt /*show blank line, show the prompt*/
pull ans /*get the answer(s) & uppercase it*/
ans = space(ans,0) /*elide all blanks. */
end /*until*/
/*stick a fork in it, we're done.*/

[edit] version 1 for PC/REXX and Personal REXX

This version of a REXX program works with PC/REXX and Personal REXX.

/*REXX program to test for a     Y   or   N     key when pressed.       */
prompt = 'Please press Y or N for verification:' /*PROMPT msg.*/
 
do until pos(ans,'NYny')\==0 /*keep prompting until answer = Y N y n */
say; say prompt /*show blank line, then show the prompt. */
ans=inkey('wait') /*get the answer(s) from the terminal. */
end /*until*/
/*stick a fork in it, we're all done. */

[edit] version 2 for PC/REXX and Personal REXX

This version is the same as above, but has a more idiomatic technique for testing the response.

/*REXX program to test for a     Y   or   N     key when pressed.       */
prompt = 'Please press Y or N for verification:' /*PROMPT msg.*/
 
do until pos(ans,'NY')\==0 /*keep prompting until user answers Y | N*/
say; say prompt /*show blank line, then show the prompt. */
ans=inkey('wait'); upper ans /*get the answer(s), also, uppercase it. */
end /*until*/
/*stick a fork in it, we're all done. */

[edit] Ruby

 
def yesno
begin
system("stty raw -echo")
str = STDIN.getc
ensure
system("stty -raw echo")
end
if str == "Y"
return true
elsif str == "N"
return false
else
raise "Invalid character."
end
end
 

[edit] Run BASIC

[loop] cls                ' Clear screen
html "Click Y or N" ' no other options
button #y, "Y", [Y] ' they either click [Y]
button #n, "N", [N] ' or they click [N]
html "<br>";msg$ ' print message showing what they entered
wait
[Y] msg$ = "You entered [Y]es": goto [loop]
[N] msg$ = "You entered [N]o" : goto [loop]
 

[edit] Scala

  println(if (readBoolean) "Yes typed." else "Something else.")

[edit] Seed7

$ include "seed7_05.s7i";
include "keybd.s7i";
 
const func boolean: yesOrNo (in string: prompt) is func
result
var boolean: yes is FALSE;
local
var char: answer is ' ';
begin
while keypressed(KEYBOARD) do
ignore(getc(KEYBOARD));
end while;
write(prompt);
repeat
answer := lower(getc(KEYBOARD));
until answer in {'y', 'n'};
yes := answer = 'y';
end func;
 
const proc: main is func
begin
writeln(yesOrNo("Press Y or N to continue "));
end func;

[edit] Tcl

Using the console (expects U*Xish stty)

proc yesno {{message "Press Y or N to continue"}} {
fconfigure stdin -blocking 0
exec stty raw
read stdin ; # flush
puts -nonewline "${message}: "
flush stdout
while {![eof stdin]} {
set c [string tolower [read stdin 1]]
if {$c eq "y" || $c eq "n"} break
}
puts [string toupper $c]
exec stty -raw
fconfigure stdin -blocking 1
return [expr {$c eq "y"}]
}
 
set yn [yesno "Do you like programming (Y/N)"]

Without a console (answer in the global variable yn; this should work in any GUI for which there is a TCL):

 
proc yesno {message} {
toplevel .msg
pack [label .msg.l -text "$message\n (type Y/N)?"]
set ::yn ""
bind .msg <Key-y> {set ::yn "Y"}
bind .msg <Key-n> {set ::yn "N"}
vwait ::yn
destroy .msg
}
 
yesno "Do you like programming?"
 
 

[edit] UNIX Shell

Works with: Bourne Again SHell
getkey() {
local stty="$(stty -g)"
trap "stty $stty; trap SIGINT; return 128" SIGINT
stty cbreak -echo
local key
while true; do
key=$(dd count=1 2>/dev/null) || return $?
if [ -z "$1" ] || [[ "$key" == [$1] ]]; then
break
fi
done
stty $stty
echo "$key"
return 0
}
 
yorn() {
echo -n "${1:-Press Y or N to continue: }" >&2
local yorn="$(getkey YyNn)" || return $?
case "$yorn" in
[Yy]) echo >&2 Y; return 0;;
[Nn]) echo >&2 N; return 1;;
esac
}

Cleaner version using bash built-ins

#!/bin/bash
 
yorn() {
echo -n "${1:-Press Y or N to continue: }"
 
shopt -s nocasematch
 
until [[ "$ans" == [yn] ]]
do
read -s -n1 ans
done
 
echo "$ans"
 
shopt -u nocasematch
}
 
yorn

[edit] Vedit macro language

Key_Purge()                                     // flush keyboard buffer
do {
#1 = Get_Key("Are you sure? (Y/N): ") // prompt for a key
#1 &= 0xdf // to upper case
} while (#1 != 'Y' && #1 != 'N')

[edit] XPL0

include c:\cxpl\codes;          \intrinsic 'code' declarations
loop [OpenI(1); \flush any pending keystroke
case ChIn(1) of \get keystroke
^Y,^y: Text(0, "yes");
^N,^n: Text(0, "no");
$1B: quit \Esc key terminates program
other ChOut(0, 7\bel\);
CrLf(0);
]
Personal tools
Namespaces

Variants
Actions
Community
Explore
Misc
Toolbox