.:: Jorge Pereira ::.

- getch() no Linux

Se você já precisou algum dia trabalhar diretamente com leituras de teclas a partir da STDIN sem a interação do <ENTER> conforme maioria das funções estilo gets(), fgets(). e estava a procura de algo no estilo getch() e percebeu que não existe implementação idêntica no Linux. pode ficar tranquilo, abaixo segue uma implementação que fiz para leitura de teclas pressionadas sem a intereção do <ENTER>.


/*
* Source: getch.c
* Autor: Jorge Pereira
* Data:  Tue Jul 29 09:35:42 BRT 2008
* Desc:  Implementacao da funcao getch() no Linux,
* podendo ser feito leitura de um unico byte por vez.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdint.h>

#ifdef getch
#undef getch
#endif
typedef unsigned int keybd_t;

keybd_t getch (void)
{
struct termio old_tty;
struct termio new_tty;;
keybd_t	key = 0;;

if (ioctl(STDIN_FILENO, TCGETA, &amp;old_tty) < 0)
{
fprintf(stderr,"Port ioctl(TCGETA) it's failed, exiting...\n");
exit(EXIT_FAILURE);
}

new_tty = old_tty;
new_tty.c_lflag &amp;= ~(ICANON | ECHO);
new_tty.c_cc[4]  = 01;

if (ioctl(STDIN_FILENO, TCSETA, &amp;new_tty) < 0)
{
fprintf(stderr,"Port ioctl(TCSETA) it's failed, exiting...\n");
exit(EXIT_FAILURE);
}

if(read(STDIN_FILENO, &amp;key, sizeof(key)) < 0)
{
fprintf(stderr,"Problems in read()\n");
exit(EXIT_FAILURE);
}

if (ioctl(STDIN_FILENO, TCSETA, &amp;old_tty) < 0)
{
fprintf(stderr,"Port ioctl(TCSETA) it's failed, exiting...\n");
exit(EXIT_FAILURE);
}

return key;
}

#if defined(RUN_MAIN)
int
main (void)
{
keybd_t key;

printf ("(*) Teste para funcao getch(), pressione  para sair!\n");

while ((key = getch()) != 0x1b)
{
char ch = (key >= 'a' &amp;&amp; key <= 'z') ||
(key >= 'A' &amp;&amp; key <= 'Z') ||
(key >= '0' &amp;&amp; key <= '9') ? key: ' ';

printf (" -> key char(%c) hex(0x%08x) dec(%d)\n", ch, key, key);
}

printf ("(*) Saindo...\n");

return EXIT_SUCCESS;
}
#endif
/* getch.c - end */

Adicionei um bloco ifdef com um main(), para que seja possível executar e testar a função. Abaixo segue exemplo de compilação.

[jorge@jiraya codigos]$ gcc -W -Wall -DRUN_MAIN -o getch getch.c
[jorge@jiraya codigos]$ ./getch
(*) Teste para funcao getch(), pressione <ESC> para sair!
-> key char(a) hex(0×00000061) dec(97)
-> key char(b) hex(0×00000062) dec(98)
-> key char(c) hex(0×00000063) dec(99)
-> key char(d) hex(0×00000064) dec(100)
(*) Saindo…
[jorge@jiraya codigos]$

Caso queira adicionar o ao seu projeto, basta remover o bloco #ifdef e utilizar normalmente! ;)

1 Comment on “- getch() no Linux”

  1. #1 Eduardo Luna
    on Aug 4th, 2008 at 12:42

    Muito legal a dica, estive procurando por algo parecido e este seu exemplo ficou ideal para minha necessidade!!!!

    Parabéns cara, seu blog e nota 10!!

Leave a Comment