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 tranqüilo, abaixo segue uma implementação chamada getch.c que fiz para leitura de teclas pressionadas sem a interação do <ENTER>. Lembrando que está e um alternativa caso não queira utilizar a função getch() existente na biblioteca ncurses e sendo obrigado a ter tal dependência incluída no seu projeto para tão pouco uso!
/*
* 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 <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#include <sys/ioctl.h>
#ifdef getch
#undef getch
#endif
typedef unsigned int keybd_t;
keybd_t getch (void)
{
struct termio old_tty; /* current terminal settings */
struct termio new_tty; /* new terminal settings */
keybd_t key = 0; /* character "buffer" */
if (ioctl(STDIN_FILENO, TCGETA, &old_tty) < 0)
{
fprintf(stderr,"Port ioctl(TCGETA) it's failed, exiting...\n");
exit(EXIT_FAILURE);
}
new_tty = old_tty; /* copy terminal settings */
new_tty.c_lflag &= ~(ICANON | ECHO); /* set flags in teminal */
new_tty.c_cc[4] = 01; /* struct for raw mode */
if (ioctl(STDIN_FILENO, TCSETA, &new_tty) < 0)
{
fprintf(stderr,"Port ioctl(TCSETA) it's failed, exiting...\n");
exit(EXIT_FAILURE);
}
if(read(STDIN_FILENO, &key, sizeof(key)) < 0)
{
fprintf(stderr,"Problems in read()\n");
exit(EXIT_FAILURE);
}
if (ioctl(STDIN_FILENO, TCSETA, &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' && key <= 'z') || (key >= 'A' && key <= 'Z') || (key >= '0' && key <= '9') ? key: ' ';
printf (" -> key char(%c) hex(0x%08x) dec(%d)\n", ch, key, key);
}
printf ("(*) Saindo...\n");
return EXIT_SUCCESS;
}
#endif
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!






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!!
Ops!
Olá! Jorge,
Muito boa essa função getch que você criou, mas pra mim, que uso kubuntu, ela só funcionou depois que googlei um pouco e descobri que devia acrescentar as bibliotecas a seguir:
#include <sys/ioctl.h>
#include <unistd.h>
#include <termios.h>
e, também, após substituir a expressão ‘&’ por ‘&’. Em seguida, resolvi testar quais bibliotecas eram realmente necessárias, comentando uma a uma. Assim, verifiquei que as bibliotecas a seguir, podiam ser comentadas ou excluídas:
//#include <string.h>
//#include <errno.h>
//#include <stdint.h>
Olá Ladislau,
Então, conforme você mesmo comentou o fato dos “&” ao invés de “&” foi causado pelo antigo plugin responsável pelo “Syntax Highlight” dos códigos!
Obrigado pelo toque!
Muito bom cara!
Era oq eu procurava
Já publicou isso no viva o linux ?
Abraço!