Popup YouTube Video
Sheerpower Logo

Making Console Applications: Prompts, Input Options, and Menus


Making Console Applications

A console application talks to a person through the screen: it prints, it asks, and it offers menus. The basics of asking are on Asking the user for Information (INPUT) — this page is the reference for everything around them: the three input statements and every option they take, and the menu system with its full set of % directives.

Each section opens with the idea; click a Show me line for the details and examples, or Expand all.

The output shown here is a text approximation. Sheerpower renders these menus graphically, in your operating system's native style; the ASCII versions are only for display on this page.

1. Three Ways to Ask

input reads one or more values and stops at a comma or a space, line input reads the whole line, and key input reads a single keystroke without waiting for Enter. All three take a prompt. A prompt written as a plain quoted string gets a question mark appended — the classic BASIC convention — while the explicit prompt option is shown exactly as written.

Show me: the three statements and the two prompt forms
input 'How many widgets': n input 'Width and height': w, h print 'n = '; n; ' area = '; w * h How many widgets? 12 Width and height? 3, 4 n = 12 area = 12
line input 'Your name: ': n1$ line input prompt 'Your name: ': n2$ line input n3$ print n1$; '|'; n2$; '|'; n3$ Your name: ? Ada Your name: Grace Linus Ada|Grace|Linus

Three lessons in one run: the short form appended ? to 'Your name: ', the prompt form did not, and a line input with no prompt shows nothing at all. Use the prompt form whenever the exact text matters.

print 'Continue (y/n)?' key input k$ print 'key = ['; k$; ']' Continue (y/n)? y key = [y]

key input returns as soon as one key is pressed; the value is that single character. It is the statement for "press any key" pauses and single-letter choices.

2. The Input Options

Options follow the prompt, comma-separated, and the list ends with a colon before the variables: line input 'Prompt', option, option: var. They control where the prompt appears, how long the program waits, what is accepted, and what happens at the end of input.

Show me: every option, with its argument
OptionArgumentWhat it does
promptstringThe prompt, shown exactly as written (no question mark added).
defaultstringText already in the field when the prompt appears; the person can accept it with Enter or type over it. For a menu, the path of the item to highlight (section 3).
lengthnumberThe width of the input field on the screen.
validstringA validation rule the answer must pass before it is accepted; a failing answer is refused and the prompt repeats. Rule words include integer, number, digits, letters, date, required, ucase, lcase, minlength n, maxlength n, pattern, yes/no, and the date layouts ymd, mdy, dmy.
timeoutnumberSeconds to wait for an answer before the statement gives up.
elapsednumeric variableReceives the seconds the person took to answer (a real gets hundredths, an integer is rounded).
eofboolean variableSet to true when there is no more input (a closed pipe, Ctrl+Z) instead of raising an error.
atrow, columnWhere the prompt appears on the screen, 1-origin.
areatop, left, bottom, rightA rectangle for multi-line text entry.
eraseErases the input area first.
attributesstringDisplay attributes for the field, such as 'bold' or 'reverse'.
menustringThe menu definition — the whole of section 3 onward.
screenstringA fill-in form definition: several fields on one screen.
dialogboxstringA dialog box definition; implies line input.
idstringAn identifier for the field, used by screen forms.

The options a program most often reaches for are timeout with elapsed, and eof:

line input 'Answer within 5 seconds', timeout 5, elapsed took: a$ print 'answer ['; a$; '] took '; took; ' seconds' Answer within 5 seconds? fast answer [fast] took .003 seconds
line input 'Line', eof done?: a$ print 'first ['; a$; '] done '; done? line input 'Line', eof done?: b$ print 'second ['; b$; '] done '; done? Line? only one line first [only one line] done 0 Line? second [] done 1

Without eof, reading past the end of input is an error; with it, the variable comes back empty and the flag says why. That is the idiom for a program that reads until its input runs out.

at places the prompt anywhere on the screen. This is the screen image captured while the program waited, with the prompt at row 5, column 10:

line input 'Name', at 5, 10: n$ print 'hello '; n$ Name? Kim hello Kim

3. Menus

A menu is a string. Items are separated by commas, an item can carry a value, an item can open a submenu, and % directives set the title, the position, the layout and the behaviour. The statement is line input menu spec$: choice$; the person moves with the arrow keys and picks with Enter, Space or a click.

print 'Welcome to the fruit stand' spec$ = '%title ' + quote$('Pick a fruit') + ', ' + 'apples, pears, ' + '%bar, ' + 'tropical = { mango, papaya }' line input menu spec$: choice$ print 'you chose '; choice$ print 'path '; _string$ Welcome to the fruit stand +---------Pick a fruit---------+ | APPLES | | PEARS | |------------------------------| | TROPICAL > | +------------------------------+

The first item is highlighted when the menu opens. %bar drew the rule, and the > marks tropical as a submenu — choosing it opens the second menu:

Welcome to the fruit stand +-----------TROPICAL-----------+ | MANGO | | PAPAYA | +------------------------------+

Choosing papaya closes both menus and the program continues:

Welcome to the fruit stand you chose PAPAYA path #3;#2
Show me: item syntax, values, submenus, and what the program gets back

Items

  • Items are comma-separated. An unquoted item is shown in upper case (apples becomes APPLES); a quoted item keeps its case exactly — "Apples".
  • text = value shows the text and returns the value:
line input menu 'Small = S, Medium = M, Large = L': size$ print 'code '; size$; ' path '; _string$ code M path #2
  • text = { items } is a submenu, nested as deeply as you like. A submenu with no %title of its own is titled with the item's text, as TROPICAL was above.

What the program gets back

  • The variable receives the chosen item's value, or its text when it has no value.
  • _string$ receives the path of the choice through the levels: #3;#2 means the third item of the top menu, then the second item of its submenu. Rules and headings are not counted.
  • Escape (or the Back item of a submenu) leaves the menu with an empty result. Ctrl+Z leaves it too and sets _exit to true — a console application should test that before trusting the result:
line input menu 'go, stop': ans$ print 'ans ['; ans$; '] exit flag '; _exit ans [] exit flag 1

Pre-selecting an item, and the other options

  • The default option names the item to highlight when the menu opens, by its path — the same form _string$ returns: default '#2' highlights the second choosable item, default '#3;#2' opens the third item's submenu on its second item. Keeping the last _string$ and passing it back as the default reopens a menu on the person's previous choice. A default that is not a path raises the illnum exception.
  • timeout and elapsed work with a menu exactly as with a prompt.
  • input menu spec$: choice$ is the same statement as line input menu.

The keys a person uses

  • Up and Down move the highlight; Delete jumps to the first item.
  • Enter, Space, Right arrow, or a click chooses the item, or opens its submenu.
  • Escape or Left arrow goes back to the calling menu; from the top menu, Escape leaves with an empty result.
  • Ctrl+Z leaves the whole menu and sets _exit.

4. The Menu Directives

A directive is a word starting with %, written among the items. There are twenty-four; they fall into three groups — where and how the menu is laid out, what appears in it besides the items, and how it behaves. Here is a menu using several at once, captured while it waited:

spec$ = '%title ' + quote$('Layout') + ', ' + '%at 3,5, ' + '%heading ' + quote$('Fruit') + ', ' + 'apples, pears, ' + '%split, ' + '%heading ' + quote$('Veg') + ', ' + 'carrots, %invalid peas, beans' line input menu spec$: pick$ print 'pick '; pick$; ' path '; _string$ +----------------------------Layout----------------------------+ |Fruit | Veg | | APPLES | CARROTS | | PEARS | PEAS | | | BEANS | +--------------------------------------------------------------+
pick APPLES path #1

%at 3,5 put the top-left corner at row 3, column 5; %split started the second column; each %heading labelled its column; %invalid peas shows an item that cannot be chosen — the path #1 counts only choosable items.

Show me: all twenty-four directives

Layout

DirectiveMeaning
%at row, colPosition of the menu; either may be center, as in %at center, center.
%splitStart a new column here.
%columns nSplit the items evenly into n columns.
%items nAt most n items per column before a new column starts.
%size nRows visible in the current column (at least 2); more items scroll.
%width nMinimum width of the current column.
%maxwidth nMaximum width of the whole menu (at least 5).
%vbarA vertical bar after the current column.
%autovbar on|offAutomatic bars between columns (on by default).
%lockstep on|offColumns scroll together (on by default).
%leftEntries flush left in their column.
%border on|offDraw the frame (on by default).
%menubarA horizontal menu bar with pull-down submenus, one row per column.

Content

DirectiveMeaning
%title "text"The title.
%message "text"A message shown while the menu is up.
%bar, %bar 'text'A rule across the column, plain or carrying text.
%heading "text"A labelled separator, in the heading colour.
%invalid itemThe next item is shown but cannot be chosen.

Behaviour

DirectiveMeaning
%multiChoose several items — section 5.
%replaceA submenu that replaces its parent instead of opening beside it; its Back item returns.
%autodisplay on|offSubmenus open as soon as their item is highlighted (on by default).
%nomouseoverNo highlighting under the mouse pointer. Top-level menu only.
%inactiveThe menu is shown as a normal window that others may overlap. Top-level only.
%attachedThe menu minimizes and restores with the console window. Top-level only.
One error for every mistake. A directive with a missing or bad argument, a top-level-only directive inside a submenu, an empty quoted item, or a menu that ends before any item all raise the same exception, Invalid input menu format. When the reason is known it is in _string$ — see the %multi rule below.
Show me: what each directive looks like on the screen

Each picture is the screen captured while the menu waited, with the part of the menu string that made the difference. Six directives have no picture because they change behaviour rather than appearance: %message (a status line while the menu is up), %autodisplay, %lockstep, %nomouseover, %inactive and %attached. %title is on every picture, and %heading, %invalid and %split are in the Layout example above.

%at center, center

spec$ = '%title ' + quote$('Centred') + ', ' + '%at center, center, ' + 'one, two, three' line input menu spec$: choice$ +-----------Centred------------+ | ONE | | TWO | | THREE | +------------------------------+

%size 3 — three rows visible, the rest scroll

spec$ = '%title ' + quote$('Only three rows') + ', ' + '%size 3, ' + 'alpha, beta, gamma, delta, epsilon, zeta' line input menu spec$: choice$ +-------Only three rows--------+ | ALPHA | | BETA | | GAMMA | +------------------------------+

%columns 2 — the items split evenly

spec$ = '%title ' + quote$('Two columns') + ', ' + '%columns 2, ' + 'jan, feb, mar, apr, may, jun' line input menu spec$: choice$ +-------------------------Two columns--------------------------+ | JAN | APR | | FEB | MAY | | MAR | JUN | +--------------------------------------------------------------+

%items 3 — a new column every three items

spec$ = '%title ' + quote$('Three per column') + ', ' + '%items 3, ' + 'jan, feb, mar, apr, may, jun' line input menu spec$: choice$ +-----------------------Three per column-----------------------+ | JAN | APR | | FEB | MAY | | MAR | JUN | +--------------------------------------------------------------+

%maxwidth 40 — the whole menu capped, the last column cut

spec$ = '%title ' + quote$('Capped at 40') + ', ' + '%maxwidth 40, %columns 2, ' + 'jan, feb, mar, apr' line input menu spec$: choice$ +--------------Capped at 40--------------+ | JAN | MAR | | FEB | APR | +----------------------------------------+

%autovbar off — no bars between columns

spec$ = '%title ' + quote$('Bars off') + ', ' + '%autovbar off, ' + 'jan, feb, %split, mar, apr' line input menu spec$: choice$ +--------------------------Bars off---------------------------+ | JAN MAR | | FEB APR | +-------------------------------------------------------------+

%vbar — a bar after this column only

spec$ = '%title ' + quote$('One bar, where asked') + ', ' + '%autovbar off, ' + 'jan, feb, %vbar, %split, mar, apr' line input menu spec$: choice$ +---------------------One bar, where asked---------------------+ | JAN | MAR | | FEB | APR | +--------------------------------------------------------------+

%border off — no frame, and so no title

print 'The line above the menu' spec$ = '%title ' + quote$('Borderless') + ', ' + '%border off, ' + 'one, two' line input menu spec$: choice$ The line above the menu ONE TWO

%bar 'text' — a rule that carries a label

spec$ = '%title ' + quote$('Rules') + ', ' + 'coffee, tea, ' + '%bar ' + quote$('cold drinks') + ', ' + 'juice, water' line input menu spec$: choice$ +------------Rules-------------+ | COFFEE | | TEA | |-------- cold drinks ---------| | JUICE | | WATER | +------------------------------+

%replace — the submenu takes the parent's place

The parent, then the screen after choosing reports: the submenu is where the parent was, not beside it. Its Back item returns.

spec$ = '%title ' + quote$('Main') + ', ' + 'reports = { %replace, %title ' + quote$('Reports') + ', daily, weekly }, ' + 'settings' line input menu spec$: a$ print 'a = '; a$ +-------------Main-------------+ | REPORTS > | | SETTINGS | +------------------------------+
+-----------Reports------------+ | DAILY | | WEEKLY | +------------------------------+
a = WEEKLY

%menubar — a horizontal bar with pull-downs

spec$ = '%menubar, ' + 'file = { open, save }, edit = { cut, paste }, help' line input menu spec$: choice$ +----------------------------------------------------------------------------- | FILE > EDIT > HELP +-----------------------------------------------------------------------------

%multi — a checklist

spec$ = '%title ' + quote$('Toppings') + ', ' + '%multi, ' + 'cheese, onions, olives' line input menu spec$: a$ print 'a = '; change$(a$, chr$(10), '|') +-----------Toppings-----------+ | [ ] CHEESE | | [ ] ONIONS | | [ ] OLIVES | +------------------------------+
a = CHEESE|OLIVES

%width 40 — a column at least 40 wide

spec$ = '%title ' + quote$('At least 40 wide') + ', ' + '%width 40, ' + 'yes, no' line input menu spec$: choice$ +------------At least 40 wide------------+ | YES | | NO | +----------------------------------------+

%left — no indent in front of the items

spec$ = '%title ' + quote$('Flush left') + ', ' + '%left, ' + 'one, two' line input menu spec$: choice$ +----------Flush left----------+ |ONE | |TWO | +------------------------------+

5. Choosing Several Items: %multi

%multi turns the menu into a checklist with Done, Back and Exit buttons. Space toggles an item; Done returns every checked item, one per line.

Show me: the result of a %multi menu, and its one rule
spec$ = '%title ' + quote$('Colours') + ', ' + '%multi, ' + 'red, green, blue' line input menu spec$: picks$ print 'picks: '; change$(picks$, chr$(10), '|') print 'count: '; pieces(picks$, chr$(10)) +-----------Colours------------+ | [ ] RED | | [ ] GREEN | | [ ] BLUE | +------------------------------+ picks: RED|BLUE count: 2

The checked items come back separated by line breaks, so pieces() counts them and piece$() takes them one at a time. The rule: a %multi menu cannot contain submenus. The menu string is refused when it is parsed, and the exception says why:

when exception in line input menu '%multi, a = {x, y}, b': ans$ use print 'error '; extype; ': '; extext$ print 'detail: '; _string$ end when error -4023 : Invalid input menu format detail: a %multi menu cannot contain submenus (an item written as name={...}): use %multi only on a menu whose items are all plain choices

Beyond the Console: Dialog Boxes

When one question is not enough and you want a whole form at once — several fields, a checkbox or two, a dropdown — reach for a dialog box: a native window driven by the same line input family, which also opens the native file and folder pickers. See Dialog Boxes: Forms, Fields, and Native File Pickers and its companion reference Dialog Box Reference: Every Tag and Attribute.

Making Console Applications Takeaways

  • input stops at a comma or space, line input takes the whole line, key input takes one keystroke.
  • A plain quoted prompt gets ? appended; the prompt option shows the text exactly as written.
  • Options are comma-separated after the prompt and end with :timeout with elapsed, eof, at, default, valid, length, area.
  • A menu is a string: comma-separated items, text = value, text = { submenu }, and % directives for title, position, columns and behaviour.
  • The program gets the chosen value, the path in _string$, and _exit when the person pressed Ctrl+Z; Escape returns an empty result.
  • %multi returns every checked item, one per line, and cannot contain submenus.
  • Every menu mistake raises Invalid input menu format, with the reason in _string$ when it is known.
Hide Description

    

       


      

Enter or modify the code below, and then click on RUN

Looking for the full power of Sheerpower?
Check out the Sheerpower website. Free to download. Free to use.