Article View: es.comp.os.linux.programacion
Article #10600Re: Comportamiento raro con getch y printf
From: Ángel Suárez Rivero
Date: Sat, 16 Feb 2002 15:33
Date: Sat, 16 Feb 2002 15:33
229 lines
6692 bytes
6692 bytes
--nextPart4296490.OQGJRl0yb3
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8Bit
Reinoso G. wrote:
> Para que no me digais :-) he mirado el c�digo fuente del showkey que lo
> hace sin curses, pero pone el teclado en modo raw o xlate mediante
> llamadas ioctl, yo buscaba algo m�s sencillo para leer un car�cter y que
> est� disponible al instante para que el programa siga su ejecuci�n antes
> de un \n.
>
> Gracias y hasta pronto.
>
>
Te paso las que yo uso para esto, en un adjunto:
Saludos.
--
-----BEGIN PGP MESSAGE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org
owGbwMvMwCR4mlF2Vp79x72Ma04kcekVZ6bnJZaUFqXasFbeDUgsSsnPU0jLL1LI
rVRwzUvPySzO4LLVJRNy1XA6+Lm7+nAWFyXmpafmOJSk5qTmZOal6qUWcxbklySW
5CsY6VUqFGQm53PWUGBPhz0zKwPIAzC/CTIV9zPMU7ypfjl0seSXuFSvXROCH7F5
fem2ZJifuOGfelOH1nE32yfv2hR5Mi6lHTEGAA==
=tKD8
-----END PGP MESSAGE-----
--nextPart4296490.OQGJRl0yb3
Content-Type: text/x-csrc; name="get_kb.c"
Content-Transfer-Encoding: 8Bit
Content-Disposition: attachment; filename="get_kb.c"
/*
* kbhit(), a keyboard lookahead monitor
* getch(), a blocking single character input from stdin
*
* Plus a demo main() to illustrate usage.
*/
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/types.h>
int getch(void);
int kbhit(void);
#define CMIN 1
#ifdef CTIME
#undef CTIME
#endif
#define CTIME 1
/*
* kbhit() -- a keyboard lookahead monitor
*
* returns the number of characters available to read.
*/
int
kbhit(void)
{
int cnt = 0;
int error;
static struct termios Otty, Ntty;
tcgetattr(0, &Otty);
Ntty = Otty;
Ntty.c_iflag = 0; /* input mode */
Ntty.c_oflag = 0; /* output mode */
Ntty.c_lflag &= ~ICANON; /* raw mode */
Ntty.c_cc[VMIN] = CMIN; /* minimum time to wait */
Ntty.c_cc[VTIME] = CTIME; /* minimum characters to wait for */
if (0 == (error = tcsetattr(0, TCSANOW, &Ntty))) {
struct timeval tv;
error += ioctl(0, FIONREAD, &cnt);
error += tcsetattr(0, TCSANOW, &Otty);
/* throw in a miniscule time delay */
tv.tv_sec = 0;
tv.tv_usec = 100;
select(1, NULL, NULL, NULL, &tv);
}
return (error == 0 ? cnt : -1 );
}
/*
* getch() -- a blocking single character input from stdin
*
* Returns a character, or -1 if an input error occurs.
*
*
* Conditionals allow compiling with or without echoing of
* the input characters, and with or without flushing pre-existing
* existing buffered input before blocking.
*
*/
int
getch(void)
{
char ch;
int error;
static struct termios Otty, Ntty;
fflush(stdout);
tcgetattr(0, &Otty);
Ntty = Otty;
Ntty.c_iflag = 0; /* input mode */
Ntty.c_oflag = 0; /* output mode */
Ntty.c_lflag &= ~ICANON; /* line settings */
#if 1
/* disable echoing the char as it is typed */
Ntty.c_lflag &= ~ECHO; /* disable echo */
#else
/* enable echoing the char as it is typed */
Ntty.c_lflag |= ECHO; /* enable echo */
#endif
Ntty.c_cc[VMIN] = CMIN; /* minimum time to wait */
Ntty.c_cc[VTIME] = CTIME; /* minimum chars to wait for */
#if 1
/*
* use this to flush the input buffer before blocking for new input
*/
#define FLAG TCSAFLUSH
#else
/*
* use this to return a char from the current input buffer, or block if
* no input is waiting.
*/
#define FLAG TCSANOW
#endif
if (0 == (error = tcsetattr(0, FLAG, &Ntty))) {
error = read(0, &ch, 1 ); /* get char from stdin */
error += tcsetattr(0, FLAG, &Otty); /* restore old settings */
}
return (error == 1 ? (int) ch : -1 );
}
/*
* a cutsie main() to demo how getch() and kbhit() work.
*/
#include <ctype.h>
int
main(void)
{
int ch, cnt;
static struct termios Otty, Ntty;
tcgetattr(0, &Otty);
Ntty = Otty;
Ntty.c_lflag &= ~ECHO;
printf("You must enter 10 characters to get\nthis program to continue: ");
fflush(stdout);
/* collect 10 characters */
while (1) {
if (10 <= (cnt = kbhit())) {
break;
}
}
tcsetattr(0, TCSANOW, &Ntty); /* disable echoing of further input */
printf("\nSTOP!");
fflush(stdout);
printf("\nNow type <Enter> to continue!");
fflush(stdout);
ch = getchar();
tcsetattr(0, TCSANOW, &Otty); /* enable echoing of further input */
printf("\n\nThe first five characters are: \"");
/*
* print a few chars, note that calling getch() will flush
* remaining buffered input.
*/
cnt = 4;
do {
printf("%c", ch);
ch = getchar();
} while (--cnt);
printf("%c\"\n\n", ch);
printf("\n\n *** Demo Menu ***\n\n");
printf(" Option Action\n");
printf(" A Exit and print an A word\n");
printf(" B Exit and print a B word\n");
printf(" C Exit and print a C word\n");
printf("\n Enter your choice: ?\b");
fflush(stdout);
while(1) {
switch (ch = getch()) {
case 'a': case 'A':
printf("%c\n\nThat is an *awesome* function!\n", toupper(ch));
break;
case 'b': case 'B':
printf("%c\n\nThat is a *beneficial* function!\n", toupper(ch));
break;
case 'c': case 'C':
printf("%c\n\nThat is a *critical* function!\n", toupper(ch));
break;
default:
continue;
}
break;
}
return 0;
}
--nextPart4296490.OQGJRl0yb3--
Technical Details
Message-ID:
<r3ul4a.ad.ln@127.0.0.1>Path:
arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!sn-xit-02!supernews.com!news.tele.dk!small.news.tele.dk!130.133.1.3!fu-berlin.de!newsfeed.bcn.ttd.net!news.bcn.ttd.net!news.mad.ttd.net!127.0.0.1!nobodyReferences:
<slrna6om3r.fa.reinoso@EA4BAO.PLLANO.ESP.EU> <74eb6167.0202150119.4c2a8ae2@posting.google.com> <slrna6qdha.7c0.sromero@compiler.servicom2000> <slrna6se1b.86.reinoso@EA4BAO.PLLANO.ESP.EU>Show Full Headers
Complete Article Headers
X-Google-Language: SPANISH,ASCII X-Google-Thread: f86c8,96738059632c4c6f X-Google-Attributes: gidf86c8,public X-Google-ArrivalTime: 2002-02-16 07:31:08 PST Path: arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!sn-xit-02!supernews.com!news.tele.dk!small.news.tele.dk!130.133.1.3!fu-berlin.de!newsfeed.bcn.ttd.net!news.bcn.ttd.net!news.mad.ttd.net!127.0.0.1!nobody From: Ángel Suárez Rivero <srangel@teleline.es> Newsgroups: es.comp.os.linux.programacion Subject: Re: Comportamiento raro con getch y printf Date: Sat, 16 Feb 2002 15:33:15 +0000 Organization: Telefonica Transmision de Datos Lines: 229 Message-ID: <r3ul4a.ad.ln@127.0.0.1> References: <slrna6om3r.fa.reinoso@EA4BAO.PLLANO.ESP.EU> <74eb6167.0202150119.4c2a8ae2@posting.google.com> <slrna6qdha.7c0.sromero@compiler.servicom2000> <slrna6se1b.86.reinoso@EA4BAO.PLLANO.ESP.EU> NNTP-Posting-Host: 213-4-244-210.uc.nombres.ttd.es Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="nextPart4296490.OQGJRl0yb3" Content-Transfer-Encoding: 7Bit User-Agent: KNode/0.6.1