/
Inicio :: Foros

 F.A.Q.F.A.Q.                  Conéctese para revisar sus mensajesConéctese para revisar sus mensajes   

Validar Numero

 
      Índice del Foro elrincondelc.com -> Principiantes C/C++
Ver tema anterior :: Ver siguiente tema  
AutorMensaje
jonabeatles



Registrado: 08 Sep 2007
Mensajes: 1

MensajePublicado: 08/09/2007 4:28 pm
Título: Validar Numero

Hola. Soy estudiante de primer año de Ing. Informática y soy un real aficionado de todo lo que es C. Así que en mi afán de que mis pequeñas aplicaciones de principiante fueran algo mas robustas, estuve todo un día tratando de validar números enteros, o sea, que si pido un numero por teclado, y presionan una letra o un carácter no dígito, te retorne un código de error. Pero ademas, también trate de que no se pasara del rango de 2^32.

Como he visto en muchos foros que preguntan como validar números, les dejo este código para que les de una base a los principiantes como yo, de como se puede validar un numero de manera casi absoluta.

Pero también quiero preguntarles a los mas expertos, como se puede optimizar el código (la función en realidad) para que quede mas reducido. Yo he aplicado todo lo que se hasta el momento y aun no me gusta (manías de uno).

Código:

#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>

#define STATUS_FAILURE 0
#define STATUS_SUCCESS 1

int ValidarInt(char *Cadena);

int main()
{
char numero[12];
int num;


   printf("Ingrese numero: ");
   gets(numero);
   if(ValidarInt(numero) == STATUS_SUCCESS){
      num = atoi(numero);
      printf("Correcto: %d", num);
   }
   else{
      printf("Error.");
   }
   getch();
   return 0;
}


int ValidarInt(char *Cadena){
int i;
char valid[5];

   if(Cadena[0] != '-'){
      if(strlen(Cadena) > 10 || Cadena[0] == '\0')
         return(0);
      
      for(i = 0; i <= strlen(Cadena); i++){           
         if(*(Cadena + i) == '\0')
            break;
         else if(isdigit(*(Cadena + i)) == 0)
            return(0);
      }
      
      if(strlen(Cadena) == 10){
         memcpy(valid, Cadena, 5);
         if(atoi(valid) > 21474)
            return(0);
         else if(atoi(valid) == 21474){
            i = 5;
            for(i = 5; i < 10; i++){
               valid[i-5] = *(Cadena + i);
            }
            if(atoi(valid) > 83647)
               return(0);
         }
      }
   }
   
   if(Cadena[0] == '-'){
      if(strlen(Cadena) > 11 || Cadena[1] == '\0')
         return(0);
      
      for(i = 1; i <= strlen(Cadena); i++){           
         if(*(Cadena + i) == '\0')
            break;
         else if(isdigit(*(Cadena + i)) == 0)
            return(0);
      }
      
      if(strlen(Cadena) == 11){
         for(i = 1; i < 6; i++){
            valid[i-1] = *(Cadena + i);
         }
         if(atoi(valid) > 21474)
            return(0);
         else if(atoi(valid) == 21474){
            for(i = 6; i < 11; i++){
               valid[i-6] = *(Cadena + i);
            }
            if(atoi(valid) > 83647)
               return(0);
         }
      }
   }
   return (1);      
}

/*
Probado con Dev-C++ y Modulo C++ de Eclipse.
*/


Bueno. Espero puedan ayudarme. Saludos y suerte.
Volver arriba
digies



Registrado: 18 Nov 2005
Mensajes: 241
Ubicación: Cono Sur

MensajePublicado: 08/09/2007 5:04 pm
Título:

Hola

Mira mi versión; tal vez puedas implementar algunas cosas en el tuyo.
Lo hice para que valide un entero, por ejemplo un año dentro de un intérvalo fijado.
Espero que te sirva.

Código:

/* Programa validar_anyo */

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

int main(void)
{
    char strAnyo[5]; int anyo, i; unsigned char e;
    do
    {
         e=0;
         printf("Ingresa el a\xA4o: "); scanf("%5s", strAnyo);
         fflush(stdin);
         if(strlen(strAnyo)>4)
         {
                puts("\nDato no v\xA0lido\a\n"); e=1;
         }
         else if(strlen(strAnyo)==1 || strlen(strAnyo)==2 || strlen(strAnyo)==3)
         {
                puts("\nDato no v\xA0lido\a\n"); e=1;
         }
         else
         {
              for(i=0; i<strlen(strAnyo); i++)
                   if(isascii(strAnyo[i])==0 || isdigit(strAnyo[i])==0)
                   {
                        puts("\nDato no v\xA0lido\a\n"); e=1; break;
                   }
              if(e!=1)
              {
                   anyo=atoi(strAnyo);
                   if((anyo>=1000 && anyo<=1581) || (anyo>=2101 && anyo<=9999))
                   {
                        puts("\nA\xA4o fuera del Calendario Gregoriano\a\n"); e=1;
                   }
              }
          }
     }
     while(e==1);     
     puts("\nA\xA4o correcto");
     printf("\n\n");
     system("pause");
     return 0;
}

Un saludo.
Volver arriba
tonilope



Registrado: 16 Oct 2005
Mensajes: 249

MensajePublicado: 08/09/2007 5:29 pm
Título:

Otra forma de validar eso:

Código:

#include <stdio.h>

int main()
{
    long long numero=0; 
    char buffer[13], pos;
   
    fgets(buffer, 13, stdin);
    buffer[strlen(buffer)-1]=0;
   
    if(buffer[0]=='-')
        pos = 1;
    else
        pos = 0;
   
    while(*(buffer+pos) != 0 && isdigit(*(buffer+pos)))
        numero = (numero << 3) + (numero << 1) + *(buffer+(pos++)) - 48;
   
    if(*(buffer+pos) == 0 && ( (buffer[0]=='-' && numero <= 2147483648) || (buffer[0]!='-' && numero <= 2147483647) ) )
          printf("\n\nNumero correcto: %lld\n", buffer[0]!='-' ? numero : numero*-1);
    else
          printf("\n\nERROR\n");
   
  return 0;

}


Teniendo en cuenta que el rango de un entero con signo de 32 bits va desde -2147483648 a 2147483647

Salu2 Wink
_________________
Be (void *) my friend


Ultima edición por tonilope el 08/09/2007 5:41 pm; editado 1 vez
Volver arriba
cheroky



Registrado: 22 Sep 2005
Mensajes: 1372
Ubicación: En ecx esperando un call

MensajePublicado: 08/09/2007 5:37 pm
Título:

La unica opcion valida para (valga la redudancia) validar de forma segura la entrada de un entero es usar las funciones de biblioteca fgets en combinacion con strtol.

Con fgets capturamos el dato en el formato array de cadena y evitamos desbordar el array destino, con strtol convertimos el array representacion numerica en un long.

Hacerlo en un relativo bajo nivel implementando nuestras funciones en C estandar ya no es posible puesto que dependeriamos de syscalls y subterfugios propios de la plataforma.


S2.
_________________
- Explícito es mejor que implícito.
- Simple es mejor que complejo.
- Complejo es mejor que complicado.
- Plano es mejor que anidado.
- Ralo es mejor que denso.
Volver arriba
      Índice del Foro elrincondelc.com -> Principiantes C/C++
Página 1 de 1Todas las horas están en GMT - 8 Horas

 
No puede crear mensajes
No puede responder temas
No puede editar sus mensajes
No puede borrar sus mensajes
No puede votar en encuestas

(c) ElRincondelC.com

Un proyecto de UrlanHeat.com