| Ver tema anterior :: Ver siguiente tema | | Autor | Mensaje |
|---|
jonabeatles
Registrado: 08 Sep 2007 Mensajes: 1
| Publicado: 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
| Publicado: 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
| Publicado: 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  _________________ 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
| Publicado: 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 | |  | | |
| No puede crear mensajes No puede responder temas No puede editar sus mensajes No puede borrar sus mensajes No puede votar en encuestas
|
|
| |