Mailinglist Archive: opensuse-programming (98 mails)
| < Previous | Next > |
Re: [suse-programming-e] How to get keyboard input without typing enter
- From: Jerry Feldman <gaf@xxxxxxx>
- Date: Wed, 18 Feb 2004 08:45:16 -0500
- Message-id: <20040218084516.76463774@xxxxxxxxxxx>
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On Tue, 17 Feb 2004 20:51:53 -1000
"Ryan Walsh" <walshfam@xxxxxxxxxxxxx> wrote:
> I'm just getting back into programming, and this is my first
> introduction to LINUX. I was wondering if anyone had a basic C
> program on how to read input from the keyboard one character at a time
> (without having to press enter)...
This is not part of standard C, but here is a program that I've had
hanging around. The Unix/C FAQ also includes something similar.
I've been using this for a while. Essentially, you set the terminal to
raw mode, (stdin is file descriptor 0). You should use the basic I/O
(eg. read(2) not the stdio routines like getc(3)).
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <termio.h>
#include <sys/ioctl.h>
static struct termio save_term;
void
SetRaw(int fd)
{
struct termio s;
/*
* Get terminal modes.
*/
(void)ioctl(fd, TCGETA, &s);
/*
* Save modes and set certain variables dependent on modes.
*/
save_term = s;
/*
* Set the modes to the way we want them.
*/
s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL);
s.c_oflag |= (OPOST|ONLCR|TAB3);
s.c_oflag &= ~(OCRNL|ONOCR|ONLRET);
s.c_cc[VMIN] = 1;
s.c_cc[VTIME] = 0;
(void)ioctl(fd, TCSETAW, &s);
}
static void
TermRestore(int fd)
{
/*
* Restore saved modes.
*/
s = save_term;
(void)ioctl(fd, TCSETAW, &s);
}
int main(int argc, char **argv)
{
int fd, n;
char buf;
fd = 0;
/Set Term to raw mode */
SetRaw(fd);
printf("Enter a digit, q or x to quit\n");
while(1) {
n = read(fd, &buf, 1);
if (n == 1) {
switch(buf) {
case 'q':
case 'Q':
case 'x':
case 'X':
printf("done\n");
TermRestore(fd);
return 0;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
printf(" %c ", buf);
fflush(stdout);
}
} else if (n == 0) {
printf("no input\n");
TermRestore(fd);
return 0;
} else {
TermRestore(fd);
perror("read\n");
return -1;
}
}
}
- --
Jerry Feldman <gaf@xxxxxxx>
Boston Linux and Unix user group
http://www.blu.org PGP key id:C5061EA9
PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (GNU/Linux)
iD8DBQFAM2xs+wA+1cUGHqkRAtc5AKCIm5+EYQaHJ0yKhm6p+PsUDPOAsACeMtU3
DM8CHhdsUH4oDxff6q1wivg=
=10Rr
-----END PGP SIGNATURE-----
Hash: SHA1
On Tue, 17 Feb 2004 20:51:53 -1000
"Ryan Walsh" <walshfam@xxxxxxxxxxxxx> wrote:
> I'm just getting back into programming, and this is my first
> introduction to LINUX. I was wondering if anyone had a basic C
> program on how to read input from the keyboard one character at a time
> (without having to press enter)...
This is not part of standard C, but here is a program that I've had
hanging around. The Unix/C FAQ also includes something similar.
I've been using this for a while. Essentially, you set the terminal to
raw mode, (stdin is file descriptor 0). You should use the basic I/O
(eg. read(2) not the stdio routines like getc(3)).
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <termio.h>
#include <sys/ioctl.h>
static struct termio save_term;
void
SetRaw(int fd)
{
struct termio s;
/*
* Get terminal modes.
*/
(void)ioctl(fd, TCGETA, &s);
/*
* Save modes and set certain variables dependent on modes.
*/
save_term = s;
/*
* Set the modes to the way we want them.
*/
s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL);
s.c_oflag |= (OPOST|ONLCR|TAB3);
s.c_oflag &= ~(OCRNL|ONOCR|ONLRET);
s.c_cc[VMIN] = 1;
s.c_cc[VTIME] = 0;
(void)ioctl(fd, TCSETAW, &s);
}
static void
TermRestore(int fd)
{
/*
* Restore saved modes.
*/
s = save_term;
(void)ioctl(fd, TCSETAW, &s);
}
int main(int argc, char **argv)
{
int fd, n;
char buf;
fd = 0;
/Set Term to raw mode */
SetRaw(fd);
printf("Enter a digit, q or x to quit\n");
while(1) {
n = read(fd, &buf, 1);
if (n == 1) {
switch(buf) {
case 'q':
case 'Q':
case 'x':
case 'X':
printf("done\n");
TermRestore(fd);
return 0;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
printf(" %c ", buf);
fflush(stdout);
}
} else if (n == 0) {
printf("no input\n");
TermRestore(fd);
return 0;
} else {
TermRestore(fd);
perror("read\n");
return -1;
}
}
}
- --
Jerry Feldman <gaf@xxxxxxx>
Boston Linux and Unix user group
http://www.blu.org PGP key id:C5061EA9
PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (GNU/Linux)
iD8DBQFAM2xs+wA+1cUGHqkRAtc5AKCIm5+EYQaHJ0yKhm6p+PsUDPOAsACeMtU3
DM8CHhdsUH4oDxff6q1wivg=
=10Rr
-----END PGP SIGNATURE-----
| < Previous | Next > |