validacion de datos en C + getch() en windows y linux sin conio

Iniciado por bdoX, 17 Enero 2012, 16:11 PM

0 Miembros y 1 Visitante están viendo este tema.

bdoX

Hola a todos:

Voy hacer mi primer aporte en el foro. Se trata de unas funciones que sirven para validar datos de entradas, y unas cuantas macros. Tambien incluye la implementación del getch() que tanto conocemos, en windows y linux.


#include <stdio.h>
#include <stdlib.h>

#ifdef WIN32
   #include <windows.h>
   #define NEWLINE      13
   #define BACKSPACE    8
#else
   #include <termios.h>
   #define NEWLINE      10
   #define BACKSPACE    127
#endif

#define TAM              20
#define SPACE            32
#define MIN_NUM          48
#define MAX_NUM          57
#define MIN_LETRA_MAY    65
#define MAX_LETRA_MAY    95
#define MIN_LETRA_MIN    97
#define MAX_LETRA_MIN    122

char getch ( );
void validar_letras (char *);
void validar_numeros (int *);

int main (void)
{

   char buffer[TAM];
   int numero;
   
   printf ( "ingrese una cadena: " );
   validar_letras (buffer);
   
   printf ( "\nla cadena ingresada es: %s\n", buffer );
   
   setbuf (stdin, NULL);
   
   printf ( "Ingrese un numero: " );
   validar_numeros ( &numero );
       
   printf ( "\nEl numero ingresado es: %d\n", numero );
 
   return 0;

}

void validar_numeros (int *numero)
{
   int i;
   char p[TAM], tecla;

   /*importante inicializar los valores
   ya que la implementacion que sigue lo amerita*/
   i = 0;
   p[0] = '\0';

   do
   {
       tecla = getch ();//atrapa un caracter sin dejar un eco

       /*BACKSPACE es la tecla para eliminar un caracter
       y el i obligaotiamente tiene que ser mayor que cero
       ya que si entra al if y tiene valor cero, el valor de i
       decrementará y p tendría un subindice -1, "p[-1]"¿?*/
       if ( i > 0 && tecla == BACKSPACE )
       {
           printf ( "\b \b" );
           p[--i] = '\0';
       }
       else
       {
           /*rango de numeros y SPACE es el espacio*/
           if ( (tecla >= MIN_NUM && tecla <= MAX_NUM)  ||
                 tecla == SPACE || tecla == '-' )
           {
               /*obligamos a que no hayan mas de un guion, y que
               el guion este al principio*/
               if ( tecla == '-' && i == 0 )
               {
                   printf ( "%c", tecla );
                   p[i++] = tecla;
               }
               else
               {
                   if ( tecla != '-' )
                   {
                       printf ( "%c", tecla );
                       p[i++] = tecla;
                   }
               }
           }
       }
   } while ((tecla != NEWLINE || p[0] == '\0') && i < TAM);
   /* NEWLINE inidica el Enter, i tiene que ser menor
   que TAM pues de lo contrario, estaría accediendo
   a memoria no reservada*/
   p[i] = '\0'; /*colocamos el fin de cadena*/
   *numero = atoi (p);
   /*convierte una cadena en un numero
   10 quiere decir que está en base decimal*/

   return ;
}

void validar_letras (char *p)
{
   int i;
   char tecla;

   /*importante inicializar los valores
   ya que la implementacion que sigue lo amerita*/
   i = 0;
   p[0] = '\0';

   do
   {
       tecla = getch ();//atrapa un caracter sin dejar un eco

       /*BACKSPACE es la tecla para eliminar un caracter o de retroceso
       y el i obligaotiamente tiene que ser mayor que cero
       ya que si entra al if y tiene valor cero, el valor de i
       decrementará y p tendría un subindice -1, "p[-1]"¿?*/
       if ( i > 0 && tecla == BACKSPACE )
       {
           printf ( "\b \b" );
           p[--i] = '\0';
       }
       else
       {
           /*rango de letras mayusculas y minusculas y SPACE es el espacio*/
           if ( (tecla >= MIN_LETRA_MAY && tecla <= MAX_LETRA_MAY)  ||
                (tecla >= MIN_LETRA_MIN && tecla <= MAX_LETRA_MIN)  ||
                 tecla == SPACE )
           {
               printf ( "%c", tecla );
               p[i++] = tecla;
           }
       }
   } while ((tecla != NEWLINE || p[0] == '\0') && i < TAM);
   /* NEWLINE inidica el Enter, i tiene que ser menor
   que TAM pues de lo contrario, estaría accediendo
   a memoria no reservada*/

   p[i] = '\0'; /*colocamos el fin de cadena*/

   return ;
}

#ifdef WIN32

char getch ( )
{
   char car;
   DWORD leidos, modo;

   GetConsoleMode ( GetStdHandle (STD_INPUT_HANDLE), &modo );
   SetConsoleMode ( GetStdHandle (STD_INPUT_HANDLE), modo &
                    !ENABLE_ECHO_INPUT & !ENABLE_PROCESSED_INPUT );
   ReadConsole ( GetStdHandle (STD_INPUT_HANDLE), &car, 1, &leidos, NULL );
   SetConsoleMode ( GetStdHandle (STD_INPUT_HANDLE), modo );
   return car;  
}

#else

char getch ( )
{

   struct termios _ter, fuente;
   char car;
 
   if ( tcgetattr (fileno(stdin), &_ter) )
   {
       perror ( "Error para obtener información\n" );
       return -1;
   }
 
   fuente = _ter;
 
   _ter.c_lflag &= ~ICANON;
   _ter.c_lflag &= ~ECHO;
   _ter.c_cc[VMIN] = 1;
   _ter.c_cc[VTIME] = 0;
 
   if ( tcsetattr (fileno(stdin), TCSANOW, &_ter) )
   {
       perror ( " Error para obtener información\n" );
       return -1;
   }
 
   car = getchar ( );

   if ( tcsetattr (fileno(stdin), TCSANOW, &fuente) )
   {
       perror ( "Error para obtener información" );
       return -1;
   }
 
   return car;
}
#endif



ojalá le sirva a alguien.

PD: este code lo publiqué en otro lado, por cualquier cosa.

saludos!




Aleix_1379


rir3760

Salvo programas sencillos no se recomienda el uso de "atoi" ya que esta retorna cero si:
A) La cadena no es valida (por ejemplo "JJJJJ")
B) El numero en la cadena es ... cero.

Para una validación a prueba de errores se debe utilizar la función "strtol" (prototipo en <stdlib.h>).

Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language