eap@bucsb.bu.edu.UUCP (Eric Pearce) (07/13/87)
I would like to write a routine that performs a repeated sequence of statements (i.e. a loop) that would check for input from the keyboard and do something according to what was typed in. Also, it would be able to continue doing the loop regardless of whether or not anything was typed in from the keyboard. like this: Begin Loop check for keyboard input if a key was pressed case 1) do something 2) do something else ... esac fi do some more stuff End Loop I used to be able to do this easily on my Apple ][. You could check a memory location to see if a key had been pressed and which one it was, without having the program wait for user input. (good for games) Is there a way to do this in C? Or maybe a different approach to the problem? (this is intended for a program on a mainframe) ANY ideas welcome! -Eric ------------------------------------------------------------------------------- Several people asked what machine I would be running this on: Encore MULTIMAX 4.3 BSD UNIX and a VAX 11/750 running the same... ------------------------------------------------------------------------------- -- ******************************************************************************* * UUCP : ..!harvard!bu-cs!bucsb!eap |-+-+ +-+-+-+-+-+-+-+\ /-+-+-+-+-+-+-+-+* * ARPANET: eap@bucsb.bu.edu | > : : : - @ - | g * * CSNET : eap%bucsb@bu-cs |-+-+-+-+-+-+-+-+-+-+/ \ +-+-+ +-+-+ +-+* * BITNET : cscc8vc@bostonu | | Blasted by ZAXXON | ; | * *******************************************************************************
edw@ius2.cs.cmu.edu (Eddie Wyatt) (07/13/87)
In article <1043@bucsb.bu.edu.UUCP>, eap@bucsb.bu.edu.UUCP (Eric Pearce) writes: > > > > I would like to write a routine that performs a repeated sequence of statements > (i.e. a loop) that would check for input from the keyboard and do something > according to what was typed in. Also, it would be able to continue doing the > loop regardless of whether or not anything was typed in from the keyboard. > This seems to be a common question in Unix. To follow, one procedure that reads one character without waiting for a return and one procedure that determines if a port is ready to read from. Modify them to fit your needs if you want. Do a man stty and ioctl to find out what the proper include files are. /************************************************************************** * * * w_read_char * * * ************************************************************************** Purpose : This function reads a single character from input without waiting for a return to be typed. Programmer : Eddie Wyatt Date : July 1987 Input : None Output : returns the current character from standard input Locals : ch - the character read omode - the old tty mode (used in restoring mode after the character is read) mode - use to change the tty mode so a single character can be read without waiting for a return Globals : stdin - not modified ************************************************************************/ int w_read_char() { struct sgttyb omode, mode; int ch; gtty(fileno(stdin),&mode); bcopy((char *) &mode, (char *) &omode,sizeof(struct sgttyb)); mode.sg_flags |= CBREAK; stty(fileno(stdin),&mode); ch = getchar(); stty(fileno(stdin),&omode); return(ch); } /************************************************************************** * * * ready_to_read * * * ************************************************************************** Purpose : This function returns TRUE if the port (fd) is ready to read from. Programmer : Eddie Wyatt Date : January 1987 Input : fd - a port Output : returns TRUE if the port is ready to read Locals : num - the number of bytes ready to read Globals : None ************************************************************************/ int ready_to_read(fd) int fd; { int num; ioctl(fd,FIONREAD,(char *)&num); return(num > 0); } -- Eddie Wyatt e-mail: edw@ius2.cs.cmu.edu terrorist, cryptography, DES, drugs, cipher, secret, decode, NSA, CIA, NRO.
rwhite@nu3b2.UUCP (Robert C. White Jr.) (07/14/87)
In article <1043@bucsb.bu.edu.UUCP>, eap@bucsb.bu.edu.UUCP (Eric Pearce) writes: > > I used to be able to do this easily on my Apple ][. You could check a memory > location to see if a key had been pressed and which one it was, without having > the program wait for user input. (good for games) > > Is there a way to do this in C? Or maybe a different approach to the problem? > (this is intended for a program on a mainframe) It would apear that an apple ][ isnt a mainframe after all ;-) SERIOUSLY: use the function ioctl to set O_NDELAY on standard input, use read to read your character. if there are no characters waiting, and you are not at an EOF condition read will return -1 and errno will be set to EAGAIN. This is how it is on our machine, check read(2) in your programmers refrence [or wherever] for details. AND REMEMBER TO ALWAS CLEAN UP YOUR ioctl BEFORE BRANCHING/EXITING FROM THE LOOP OR GO UP IN FLAMES! Robert. Disclaimer: My mind is so fragmented by random excursions into a wilderness of abstractions and incipient ideas that the practical purposes of the moment are often submerged in my consciousness and I don't know what I'm doing. [my employers certainly have no idea]
john@bby-bc.UUCP (john) (07/17/87)
> SERIOUSLY: use the function ioctl to set O_NDELAY on standard input, > use read to read your character. if there are no characters waiting, and you > are not at an EOF condition read will return -1 and errno will be set to > EAGAIN. > > This is how it is on our machine, check read(2) in your programmers > refrence [or wherever] for details. AND REMEMBER TO ALWAS CLEAN UP > YOUR ioctl BEFORE BRANCHING/EXITING FROM THE LOOP OR GO UP IN FLAMES! Isn't it supposed to return 0 if there are no characters read. Also isn't there an ioctl() settable value that specifies the minimum number of characters which must be in the buffer before a request is satisfied, along with a time period after which this many characters don't need to be there? john
guy%gorodish@Sun.COM (Guy Harris) (07/18/87)
> > SERIOUSLY: use the function ioctl to set O_NDELAY on standard input, > > use read to read your character. if there are no characters waiting, and you > > are not at an EOF condition read will return -1 and errno will be set to > > EAGAIN. > Isn't it supposed to return 0 if there are no characters read. It's like this: In systems that implement 4.[23]BSD-style no-delay I/O, if there are no characters waiting, "read" will return -1 and "errno" will be set to EWOULDBLOCK. In systems that implement System V-style no-delay I/O: if the descriptor doesn't refer to a stream, "read" will return 0; if the descriptor does refer to a stream, "read" will return -1 and "errno" will be set to EAGAIN. S5 prior to R3 didn't have streams. (Note that some systems may implement both styles of no-delay I/O.) In POSIX-style non-blocking I/O (selected with O_NONBLOCK, not O_NDELAY), "read" will return -1 and "errno" will be set to EAGAIN. I don't know if any systems implement this yet. (If your system doesn't define O_NONBLOCK, it doesn't implement it.) > Also isn't there an ioctl() settable value that specifies the minimum number > of characters which must be in the buffer before a request is satisfied, > along with a time period after which this many characters don't need to > be there? There is, but not under 4.[23]BSD; the person in question is running systems based on 4.[23]BSD. In those systems, there is an "ioctl" call FIONREAD that will tell you how many characters are waiting to be read; with this, you don't have to go into no-delay mode (and thus don't have to leave it, either). This is arguably more convenient. Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com
mouse@mcgill-vision.UUCP (der Mouse) (07/24/87)
In article <805@nu3b2.UUCP>, rwhite@nu3b2.UUCP (Robert C. White Jr.) writes: > In article <1043@bucsb.bu.edu.UUCP>, eap@bucsb.bu.edu.UUCP (Eric Pearce) writes: >> I used to be able to do this [check for keyboard input without >> waiting] easily on my Apple ][. >> Is there a way to do this in C? This is a system-dependent area; presumably you are talking about C under UNIX. C per se does not address this sort of question - all operating system interface issues are handled through library routines. Unfortunately, there is enough variation across different versions of UNIX to make it impossible to give a blanket answer. > [U]se the function ioctl to set O_NDELAY on standard input, Please specify what flavor of UNIX! Under 4.3 BSD, for example, O_NDELAY is a flag to open(), not something one uses with ioctl() (the ioctl() is called FIONBIO, also usable with fcntl()). > [if no input and not EOF], read will return -1 and errno will be set > to EAGAIN. Another difference. Under 4.3, errno is set to EWOULDBLOCK. Please qualify such statements with what flavor of operating system your question or answer is for! (Yes rwhite, I know you said "on our system", but that doesn't help eap decide whether it applies to his system.) So, to sum up: it depends on your system. Under most (all?) current variants of UNIX, it is possible, but the details of how depend on the particular system. (I can provide detail for 4.3BSD UNIX, and general ideas for 4.2BSD, but please send mail rather than cluttering the net!) der Mouse (mouse@mcgill-vision.uucp)
rsh27@chemabs.UUCP (Robert S. Hall) (07/27/87)
In article <1043@bucsb.bu.edu.UUCP> eap@bucsb.UUCP (Eric Pearce) writes: >I would like to write a routine that performs a repeated sequence of statements >(i.e. a loop) that would check for input from the keyboard and do something >according to what was typed in. Also, it would be able to continue doing the >loop regardless of whether or not anything was typed in from the keyboard. On a System V version of Unix you could open stdin using O_NDELAY (By the way on our Ultrix 1.2 system, in System V emulation mode, a program that uses O_NODELAY mode on the keyboard will cause a user to be logged off when it terminates.) On 4.[2,3] Berkley Unix you could use "ioctl(0,FIONREAD,&lngintvar);" this will return the number of characters that are ready to be returned by a read call in a long int variable named "lngintvar". See the "tty(4)" documentation for more information. 6
gwyn@brl-smoke.ARPA (Doug Gwyn ) (07/28/87)
In article <196@chemabs.UUCP> rsh27@UNIX14.UUCP (PUT YOUR NAME HERE) writes: >(By the way on our Ultrix 1.2 system, in System V emulation mode, a program >that uses O_NODELAY mode on the keyboard will cause a user to be logged off >when it terminates.) That's inherent in O_NDELAY. If you don't reset it, when the shell tries to read from the terminal it gets back what it interprets as EOF and exits.
acs60222@zach.fit.edu ( ENRIQUEZ) (07/20/89)
I have a simple question regarding keyboard input. Is is possible to trap the input (i.e. single character) using a routine such as readln (kbd,char); in Pascal. I am tired of getting a bad character AND a \n character when checking for valid user input. Also, I don't like having to hit <return> :-( Thanks.... mark enriquez (acs60222@zach.UUCP)
dhesi@bsu-cs.bsu.edu (Rahul Dhesi) (07/21/89)
In article <538@winnie.fit.edu> acs60222@zach.UUCP ( ENRIQUEZ) writes: > >I have a simple question regarding keyboard input. Is is possible to >trap the input (i.e. single character) using a routine such as > > readln (kbd,char); > >in Pascal. > >I am tired of getting a bad character AND a \n character when checking >for valid user input. Also, I don't like having to hit <return> :-( > >Thanks.... mark enriquez (acs60222@zach.UUCP) I am quoting the entire article and directing follow-ups to comp.lang.pascal. There may be some shortcomings in your Pascal compiler and/or its documentation. The '\n' character is not defined in Pascal. Let's assume by this you mean 'newline'. However, 'readln' in pascal cannot ever return a newline. It returns a blank if you do attempt to read a newline character. Having to hit 'return' is necessary if you want to edit a partially-typed line. Single-character input is probably possible but a very system-dependent thing. You will have to tell the terminal driver to do single-character input, and once you have done so, you should use 'read' (which can indeed read a single character) rather than 'readln' (which always scans for and skips past a newline following anything just read). -- Rahul Dhesi <dhesi@bsu-cs.bsu.edu> UUCP: ...!{iuvax,pur-ee}!bsu-cs!dhesi
acs60222@zach.fit.edu ( ENRIQUEZ) (07/22/89)
Hmmmm, it seems I have been misunderstood... My question was is there a C equivilent to the READ (kbd,char) (not READLN, my mistake) availible in pascal. If not, there must be a C procedure that can be written to accomplish this simple task. If someone can get me started, I'm sure I can figure it out. All I want to do is get single-character input without having to hit return. mark
dhesi@bsu-cs.bsu.edu (Rahul Dhesi) (07/22/89)
In article <539@winnie.fit.edu> acs60222@zach.UUCP ( ENRIQUEZ) writes: >Hmmmm, it seems I have been misunderstood... Oops! Sorry about that. I really did misunderstand. >My question was is there a C [equivalent] to the READ (kbd,char) (not >READLN, my mistake) [available] in pascal.... ... >All I want to do is get single-character input without having to >hit return. "How do I do single-character input without having to hit return" is a Very Commonly Asked Question. Probably the closest C analog to the Pascal construct "read (file, char-variable)" is something like this: c = getc (stdin); /* can also use c = getchar() */ However, neither the Pascal nor the C construct guarantee "raw" input, i.e., reading a character from the device without waiting for an entire line to be typed. To do raw input you must do something special to tell the device driver not to wait for a complete line. Under VAX/VMS you can use an $QIO system call to do raw input. Under MS-DOS you must use an MS-DOS-specific "ioctl" system call to put the device driver into raw mode. (Or you can do an MS-DOS-specific raw console input system call, for which there is no corresponding standard library function in C.) Under the **IX family you can either do an ioctl() (a different one) or do something like system ("stty raw"); /* more portable, slower, than ioctl() */ to put the tty driver into raw mode. Your best bet, therefore, is to consult both your operating system and your compiler manuals. Once you have told the device driver to do raw input, you may still need to set your stdin stream to unbuffered with a setbuf() function call. Alternatively, you could use a low-level system call for the actual read, which again is highly system-dependent and not part of the C language. -- Rahul Dhesi <dhesi@bsu-cs.bsu.edu> UUCP: ...!{iuvax,pur-ee}!bsu-cs!dhesi