Consultar entrada estandar(teclado)(no bloqueante)(estandar)

Consulte acerca de programas, técnicas, algoritmos etc.

Consultar entrada estandar(teclado)(no bloqueante)(estandar)

Notapor lacabra25 » Mar Jul 28, 2009 9:20 pm

Hola a todos, estoy intentando poder consultar si se ha pulsado alguna tecla para en dicho caso poder obtenerla y si no se ha pulsado ninguna tecla continuar con la ejecucion del programa. Si usara getchar la ejecucion se quedaria a la espera de que se pulse alguna tecla, pero necesito que no se quede a la espera sino que si no se pulsa una tecla continue la ejecucion.

Si es posible prefiero una solucion que use las bibliotecas estandar y que de ese modo sea portable y pueda usarla en GNU/Linux asi como en Windows (pero principalmente en GNU/Linux).
Avatar de Usuario
lacabra25
 
Mensajes: 222
Registrado: Mié Abr 02, 2008 9:45 pm
Ubicación: Tenerife (España)

Notapor lacabra25 » Sab Ago 01, 2009 12:53 am

Hola a todos, ya tengo una solucion para la lectura del teclado de forma no bloqueante es una mezcla de cambiar algunos aspectos de la configuracion de la terminal (de lo ke no tengo ni idea ya ke parte del codigo es sacado de ejemplos que encontre que no funcionaban del todo bien) y un poco de codigo igual que el que tuve que usar al programar SNL para los grupos de conexiones de sockets. Segun estuve leyendo de donde obtuve el codigo de los ejemplos el cambio en la configuracion de la terminal es por que la terminal en GNU/Linux por defecto trabaja de forma bloqueante, trabaja normal y cuando necesita algo se para para que el usuario escriba o pulse alguna tecla, por lo que hace es obtener la configuracion de la terminal, cambiar las opciones de la terminal para que trabaje de forma no bloqueante, con grupos de sockets y la funcion select se comprueba si la entrada estandar tiene algun caracter pendiente o a sucedido algo, obtiene el caracter de la tecla pulsada, comprueba que se obtuvo el caracter de forma correcta y restaura la terminal a su configuracion anterior. El codigo que encontre fallaba en que despues del select no comprobaba que fuese la entrada estandar la que verdaderamente tuviese algun caracter pendiente o algun suceso despues del select y en que no comprobaba que la funcion select no devolviese -1 y que read devolviese 1. Os dejo la funcion que he escrito finalmente con la que leer una tecla de forma no bloqueante:
Código: Seleccionar todo
char tecla_pulsada(void){
char t='\0';
static struct termios oldconsola,consola;
fd_set rfd;
struct timeval timeout;
/* Leer los parametros asociados a la consola */
if (tcgetattr(STDIN_FILENO,&consola)==-1) {
   t= '\0';
}else{
   /* Almacenar parametros para su posterior recuperacion*/
   oldconsola = consola;
   /* Cambiar parametros */
   consola.c_cc[VMIN]=1;
   consola.c_lflag&=~(ECHO|ICANON); 
   if(tcsetattr(STDIN_FILENO,TCSANOW,&consola)==-1){
      t= '\0';
   }else{
      timeout.tv_sec  = 0;
      timeout.tv_usec = 10000;
      FD_ZERO(&rfd);
      FD_SET(STDIN_FILENO,&rfd);
      if(select(STDIN_FILENO+1,&rfd,NULL,NULL,&timeout) != -1){
         if(FD_ISSET(STDIN_FILENO, &rfd)){
            read(STDIN_FILENO,&t,1);
         }
      }else{
         t= '\0';
      }
      /*recuperando la terminal anterior*/
      tcsetattr(STDIN_FILENO,TCSANOW,&oldconsola);
   }
}
return t;
}


Aprovecho tambien para dejaros un poco de codigo con el que se puede mostrar una barra "/" girando mientras el programa espera o hace cualquier cosa esperando a que el usuario pulse alguna tecla. El codigo que se pone donde se quiera escribir la barra girando es:
Código: Seleccionar todo
printf("%c", barra_girando());
printf("%c[1D", 27);


Y el codigo de la funcion barra_girando(), que es la funcion que devuelve el caracter apropiado para hacer la animacion de la barra girando:
Código: Seleccionar todo
char barra_girando(void){
static unsigned int f=0;
char s=' ';
if(f == 0){
   s= '\\';
}else if(f == 1){
   s= '|';
}else if(f == 2){
   s= '/';
}else if(f == 3){
   s= '-';
}
f++;
f= f%4;
return s;
}


Se que esto no tiene valor cuando se programa usando bibliotecas graficas como SDL, pero se puede usar por ejemplo para juegos en modo texto, para programar un servidor para un juego y cualquier otra cosa que se os ocurra.
Esta cuenta ahora a pasado a la cuenta jhg
Avatar de Usuario
lacabra25
 
Mensajes: 222
Registrado: Mié Abr 02, 2008 9:45 pm
Ubicación: Tenerife (España)


Volver a General

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado

cron