Programming and Animation

Sunday, November 06, 2005

How to get(or read) arrow key input in a C program?

How to get(or read) arrow key input in a C program?
Hello friends,

This is the most important topic in C programming.

How to read the arrow keys in a C program?

This was an interesting discussion in many forums and still going on.
Here is some information that i extracted from them:

ISO C has no concept of 'arrow keys', or 'keys',
or 'keyboards'. All i/o is expressed with
'streams of characters'. How a keyboard or
other input device presents this stream to
a C program is platform-specific.
You could unbuffer your input stream so that you could read
one character at a time from the OS, but the OS or shell
might be buffering the characters until end of line (or end of file)
instead of delivering them upwards immediately. There is no
mechanism in the C standard to ask the OS to deliver the keypresses
individually.

The only way is to use nonstandard methods.

Each OS would do this a different way, for instance DOS might require a SIGINT or
something (I seem to recall handling the mouse used an int86() call),
whereas Windows would return an event to your program that you can
handle

If you are willing to weaken down to POSIX.1 instead of pure portable
C, then POSIX.1 has appropriate mechanisms.
POSIX is a ieee standard about OS interfaces.more information can be
found at ieee.org.

termcap or terminfo give you convenient ways of representing which
character sequence means which arrow key. If you have turned off echo
and all you need is to know which arrow key has been pressed, then
terminfo / termcap or any other such correspondance table would do just
as well.

Curses is a library built on top of termcap/terminfo.
termcap and terminfo are databases of terminal device capability
information. The original termcap was developed by Bill Joy to make
vi portable to terminals other than the ADM3a, sometime in the late
1970s or early 1980s, and predates the curses library considerably.
The original curses was written by Ken Arnold in 1986; his paper
"Screen Updating and Cursor Movement Optimization" notes right in the
front matter that "[t]hese routines all use the termcap(5) database",
and credits Bill Joy.

If you want to be able to position the cursor to a particular point
on the screen, -then- you bring in curses rather than reinventing the
wheel. Provided, that is, that you are working with a text-based
output rather than a graphical output.... but of course if you
are working with graphical output, you are rather distant from
the original goal of using pure C to deal with arrow keys.

Terminfo, some versions of termcap, and some versions of curses have support for these non-ASCII keys. Typically, a special key sends a multicharacter sequence (usually beginning with ESC, '\033'); parsing these can be tricky. (curses will do the parsing for you, if you call keypad first.)

Under MS-DOS, if you receive a character with value 0 (not '0'!) while reading the keyboard, it's a flag indicating that the next character read will be a code indicating a special key. See any DOS programming guide for lists of keyboard codes. (Very briefly: the up, left, right, and down arrow keys are 72, 75, 77, and 80, and the function keys are 59 through 68.)

Another method is using the ncurses.h header.
Here is a link for that:
Arrow key scanning.

Here is a link for the ncurses documentation:
ncurses.h


In DOS, there are many ways. One way is by using the conio.h header file.
By using getch() and getche() functions.
There is another way by using kbhit( ) function.

The arrow and the Esc keys and various other key inputs cannot be read by the scanf( ) function. These keys are special in the sense they are identified be their 'scan codes'.
In fact every key on the keyboard has a unique scan code which is passed to the computer everytime a key is pressed. The following function with the help of the
kbhit( ) function can scan the key that has been pressed:

CPP / C++ / C Code:

/* this routine returns the 'scan code' of the key that has been hit */

#include
int get_scancode( )
{
union REGS inregs, outregs ;

while( !kbhit( ) ) /* while the keyboard is inactive */
; /* do nothing */

inregs.h.ah = 0 ;
int86(22, &inregs, &outregs) ;
return ( outregs.h.ah ) ;
}


The function module above in C returns the scan code of the keys that are hit.
Following is a list of keys and their respective scan codes:

up arrowkey 72
downarrow key 80
leftarrow key 75
rightarrow key 77

Finally, here is the information given by GID Forums senior member Dave:

Compiler-specific functions such as getch() are traditional for Microsoft DOS and Windows compilers such as Borland (from the earliest TurboC up to the current versions). These are very useful, and, since there are no standard library functions that do the same thing, it's appropriate to use getch(), kbhit(), etc. if they are present with your compiler.

For Linux, the possibilities are numerous, using ioctl() calls to make the input stream "raw" (unbuffered and, therefore untranslated). has useful functions on my Linux systems.

Here is an example of something that I have used in Linux to take the place of getch() for inhibiting console output when the user enters a password:

How to hide characters as they are keyed on

You can play around with it in Linux if you want to see how the arrow and function keys work on your system.

This also works for me with gnu gcc on my Windows XP system.

Note that not all keyboards in all countries in the world actually have the same keycodes.

Regards,
Paramesh.

0 Comments:

Post a Comment

<< Home