Foros del Web » Programación para mayores de 30 ;) » C/C++ »

problema con enteros u caracteres

Estas en el tema de problema con enteros u caracteres en el foro de C/C++ en Foros del Web. Bueno la pregunta es sencilla, necesito validar cuando el usuario ingresa un entero o un char, ya que en el programita siguiente en la función ...
  #1 (permalink)  
Antiguo 25/04/2012, 15:54
 
Fecha de Ingreso: febrero-2011
Mensajes: 108
Antigüedad: 13 años, 9 meses
Puntos: 4
problema con enteros u caracteres

Bueno la pregunta es sencilla, necesito validar cuando el usuario ingresa un entero o un char, ya que en el programita siguiente en la función pedirOpcion me captura lo que sea (entero o caracter, y no deberia ser por que yo le di valor int a la variable opcion, ademas en la siguiente funcion elegirMenu(int o) estoy haciendo la validacion para que el programa haga cosas solo con 4 numeros)....

O sea que cuando corro el programa y le pongo una opcion en char el programa se me queda pegado en

Opcion invalida. Presione una tecla para continuar.....

Aqui el codigo

Código:
#include <stdio.h>
#include <stdlib.h>


int main()
{
    int opcion;
    do{
    dosLineas();
    pantallaInicio();
    opcion = pedirOpcion();
    elegirMenu(opcion);
    }
    while (opcion > 4 || opcion <=0);
    

  system("PAUSE");	
  return 0;
}

//saltar dos lineas
void dosLineas()
{
     printf("\n\n");
}

//inicio del sistema, titulo y menus
void pantallaInicio()
{
     printf("\t\t*********************************************\n");
     printf("\t\t*                                   SISTEMA X                                   *\n");
     printf("\t\t*********************************************\n");
     printf("\t\t*                                             *\n");
     printf("\t\t*                   Menu                      *\n");
     printf("\t\t* 1. Opcion 1                                 *\n");
     printf("\t\t* 2. Opcion 2                                 *\n");
     printf("\t\t* 3. Opcion 3                                 *\n");
     printf("\t\t* 4. Salir                                    *\n");
     printf("\t\t*                                             *\n");
     printf("\t\t***********************************************\n");
     dosLineas();
}

//funcion para solicitar una opcion al usuario, retorna el numero de opcion
int pedirOpcion()
{
    int opcion;
    printf("Ingrese una opcion : ");
    scanf("%d",&opcion); 
         
    return opcion;
}

//funcion que determina que realizar en el programa dependiendo de la opcion
//escogida por el usuario, la cual se pasa en el parametro de la funcion
void elegirMenu(int o)
{
    switch(o)
    {
        case 1: printf("opcion 1");break;
        case 2: printf("opcion 2");break;
        case 3: printf("opcion 3");break;
        case 4: exit(0);
                break;
        default: printf("Opcion invalida.");
                 dosLineas();
                 system("PAUSE");
                 system("cls");
                 break;    
    }  
}
  #2 (permalink)  
Antiguo 25/04/2012, 17:30
 
Fecha de Ingreso: diciembre-2011
Ubicación: CABA
Mensajes: 433
Antigüedad: 12 años, 10 meses
Puntos: 94
Respuesta: problema con enteros u caracteres

Hola! una solucion posible podria ser tomar lo que retorna scanf y validarlo.
La funcion scanf retorna el número de datos de entrada asignados y si hubo algun error en la asignacion retorna cero, ej:

Código C:
Ver original
  1. do {
  2.   printf("Ingrese un numero\n");
  3.   c=scanf("%d",&opcion); // si se ingresa un caracter, scanf retorna cero
  4.   }while(c>0);

Saludos
  #3 (permalink)  
Antiguo 27/04/2012, 08:32
 
Fecha de Ingreso: febrero-2011
Mensajes: 108
Antigüedad: 13 años, 9 meses
Puntos: 4
Respuesta: problema con enteros u caracteres

Código:
do {
     printf("Ingrese un numero\n");
     c=scanf("%d",&opcion); // si se ingresa un caracter, scanf retorna cero
     }while(c>0);
Gracias por tu respuesta, pero ojala tranformara en 0 si el usuario ingresa un char o una cadena... mira he perfeccionado validando que reconosca 5 numeros y los demas los convierta a 0, esto me sirve cuando el usuario ingresa numeros invalidos (fuera de 1 o 5)... pero el problema es cuando ingresa un caracter

Código:
int pedirOpcion()
{
    int opcion, a;
    printf("\t\tIngrese una opcion : ");
    scanf("%d",&opcion);
     
    //validar si la opcion ingresada por el usuario esta entre 1 y 5, cualquier
    //otra opcion la transformara en 0
    if (opcion>0 && opcion<6)
    {
         return opcion;
    } 
    else 
    {
         opcion=0;
         return opcion;
    }
    
}
Como veras esta funcion retorma la opcion y haciendo pruebas cuando agrego un caracter o cadena transforma opcion en 0 pero se pega el programa, no pasa lo mismo cuando es cualquier tipo de numero, hace su trabajo normal, si esta sobre 5 lo tranforma a 0

La pregunta es, ¿existe alguna forma de que el programa no se pegue?
  #4 (permalink)  
Antiguo 27/04/2012, 08:45
 
Fecha de Ingreso: abril-2010
Ubicación: Rosario
Mensajes: 1.850
Antigüedad: 14 años, 7 meses
Puntos: 228
Respuesta: problema con enteros u caracteres

Código C:
Ver original
  1. #include <stdio.h>
  2.  
  3.  
  4.  
  5. int pedirOpcion()
  6. {
  7.     int opcion, a;
  8.     do {
  9.     printf("\t\tIngrese una opcion : ");
  10.     a = scanf("%d",&opcion);
  11.     while( getchar() != '\n');
  12.  
  13.     } while ( a != 1 || !( 0 < opcion && opcion < 5)  );
  14.     return opcion;
  15.    
  16. }
  17.  
  18. int main()
  19. {
  20.     pedirOpcion();
  21.  
  22. }

Tienes que combinar las dos cosas y tener en cuenta que el scanf no consume la entrada si no puede detectar el formato que desea. Es decir si vos le pedis un entero y lo primero que encuentra es una letra, esa letra la deja en el buffer y sale con error. Asi que agregue un pequeña linea que vacia el buffer para evcitar ese pegado que vos mencionas. (creo que a eso te referias con pegado)

Saludos
  #5 (permalink)  
Antiguo 27/04/2012, 10:21
 
Fecha de Ingreso: febrero-2011
Mensajes: 108
Antigüedad: 13 años, 9 meses
Puntos: 4
Respuesta: problema con enteros u caracteres

Increible, con la solucion de sam90 no se pega, pero quedo igual, por que encontre la solucion pero no entendi lo que hace esta funcion, si me lo pudieras explicar te lo agradeceria, por que necesito aplicarlo a todo el programa ya que siempre se me pega en situaciones similares

Código:
int pedirOpcion()
{
    int opcion, a;
    do {
    printf("\t\tIngrese una opcion : ");
    a = scanf("%d",&opcion);
    while( getchar() != '\n'); //que hace este while solo sin do ni
                                         //sentencias dentro, me imagino que esto es lo
                                        //que soluciona el problema

    //este while por que le da una condicion de que a sea distinto de 1 si ya esta incluido
   //en la segunda condicion !( 0 < opcion && opcion < 5) 

    } while ( a != 1 || !( 0 < opcion && opcion < 5)  );
    return opcion;
    
}
agradeceria tu respuesta, nunca habia visto un while que no tenga sentencias para hacer
  #6 (permalink)  
Antiguo 27/04/2012, 11:01
 
Fecha de Ingreso: diciembre-2011
Ubicación: CABA
Mensajes: 433
Antigüedad: 12 años, 10 meses
Puntos: 94
Respuesta: problema con enteros u caracteres

Hola! mirando lo que dijo cada uno te respondo:
Cita:
que hace este while solo sin do ni sentencias dentro???
Cita:
el scanf no consume la entrada si no puede detectar el formato que desea. Es decir si vos le pedis un entero y lo primero que encuentra es una letra, esa letra la deja en el buffer y sale con error. Asi que agregue un pequeña linea que vacia el buffer(la linea es el while, lo que hace el getchar es tomar todos esos datos del bufer; digamos que "limpia" el bufer) para evitar ese pegado

Cita:
este while por que le da una condicion de que a sea distinto de 1 si ya esta incluido en la segunda condicion !( 0 < opcion && opcion < 5)?????
Cita:
La funcion scanf retorna el número de datos de entrada asignados y si hubo algun error en la asignacion retorna cero
Una cosa es lo que retorna scanf y otra es el valor que se almacena en opcion, son dos cosas distintas. Si a!=1 es porque hubo un error en el ingreso del dato. La otra condicion valida que opcion tenga un valor entre 1 y 5

Saludos
  #7 (permalink)  
Antiguo 27/04/2012, 11:45
 
Fecha de Ingreso: febrero-2011
Mensajes: 108
Antigüedad: 13 años, 9 meses
Puntos: 4
Respuesta: problema con enteros u caracteres

Ahhhhh, entiendo lo del a!=1, si el numero no esta entre 1 y 5, el valor que toma a como error puede ser cualquier numero menos el 1, que indicaria no hay error

while( getchar() != '\n');

Este es el que no logro procesar, entiendo que cuando se le pasa un valor que no espera el scanf, se llena el buffer (me imagino que es el valor reservado de la variable opcion en memoria) con esa letra y el while
libera ese buffer... pero en donde dice que si el valor es correcto no borre el buffer, en donde dice que el buffer que se borre sea el de opcion??
Miren lo que yo entiendo de esa expresion es:
mientras que la captura de un char sea distinto a un salto de linea...(y no hace nada) entonces por eso no le encuentro sentido

Disculpen por no entender enseguida

Última edición por sefirotxx; 27/04/2012 a las 11:54
  #8 (permalink)  
Antiguo 27/04/2012, 12:48
 
Fecha de Ingreso: diciembre-2011
Ubicación: CABA
Mensajes: 433
Antigüedad: 12 años, 10 meses
Puntos: 94
Respuesta: problema con enteros u caracteres

Paso x paso xD:
1º el scanf retorna la cantidad de numeros ingresados correctamente. Si haces a=scanf("%d",&var); e ingresas un valor entero(osea un valor correcto, ej: 45), scanf retorna 1, a=1
Ahora si haces a=scanf("%d %d",&var1,&var2); e ingresas dos valores enteros(7 y 25), scanf retorna 2, a=2. ¿Pero que pasa si ingresas un valor correcto(ej: 9) y otro mal(un caracter 'm')?? scanf va a retornar 1, a=1 ¿xq? porque solo se ingreso un valor bien el otro no era un entero
Volviendo al programa: a=scanf("%d",&opcion); si vos ingresas un entero a=1; si vos ingresas algo q no sea un entero a=0. Es por esto que hay q poner como condicion a!=1. Si "a" es distinto de 1 es porque se ingreso mal el dato y el bucle do-while se va a seguir ejecutando hasta que se ingrese un entero
La otra condicion !( 0 < opcion && opcion < 5) es para que opcion este entre 1 y 5 PERO no tiene nada q ver la variable "a" con "opcion". Esta condicion tambien hace que el bucle continue cuando no se ingresa un numero entre 1 y 5

2º El funcionamiento de while( getchar() != '\n');
Tenemos scanf("%d",&opcion); supongamos que se ejecuta esto, por consola ingresamos un numero e inmediatamente despues se ingresa un ENTER, el numero se almacena en opcion y el ENTER queda en el bufer. Ahora en vez de ingresar un numero ingresamos tres letras "abc", en opcion no se almacena nada ya que hubo un error en el ingreso(scanf retorna 0) pero a b y c se almacenan en el bufer. Esto provoca que posteriores lecturas del scanf tambien tengan error
Sabiendo q la funcion getchar lo que hace es tomar un caracter del bufer, y siguiendo con el ejemplo de ingreso "abc"...Si solo se hubiera echo getchar(); se tomaria el el caracter 'a' pero b y c quedarian aun en el bufer. Es por esto que se hace el bucle while para que getchar tome todos los caracteres del bufer inclusive el ENTER

Espero se haya entendido algo :S

Saludos

Última edición por cesar_casla; 27/04/2012 a las 13:02
  #9 (permalink)  
Antiguo 27/04/2012, 13:14
 
Fecha de Ingreso: febrero-2011
Mensajes: 108
Antigüedad: 13 años, 9 meses
Puntos: 4
Respuesta: problema con enteros u caracteres

Ufff gracias por tu explicacion, entendi super bien, aunque no termina de confundirme lo del while por que siempre lo he usado como que el while da una condicion para que un procedimiento se repita hasta que esa condicion no sea valida

ya sea antes
do{procedimiento}while(condicion);

o despues
while(condicion){procedimiento}

nunca lo habia visto asi
while(condicion);

entonces tu me explicas que el while esta haciendo algo (borrando del buffer) pero yo solo veo que tiene una condicion (y la condicion la entiendo asi : si existe un caracter en el buffer que sea distinto a un espacio ) y despues no hace nada... lo entenderia mejor si despues de ese while borrara algo... pero al parecer lo esta haciendo dentro de la misma condicion, lo cual me confunde mucho

xDD aunque entendi todo lo que me explicaste, gracias!!
  #10 (permalink)  
Antiguo 27/04/2012, 15:58
 
Fecha de Ingreso: abril-2010
Ubicación: Rosario
Mensajes: 1.850
Antigüedad: 14 años, 7 meses
Puntos: 228
Respuesta: problema con enteros u caracteres

Mira lo del While es facil: Yo uso un while(condicion){procedimiento} donde procedimiento es nulo... Nada mas que en la condicion tengo una funcion que es la que consume el buffer. (getchar)

Si te gusta mas puede ser asi:

Código C:
Ver original
  1. do{
  2.  c= getchar();
  3. }while( c  != '\n');
  #11 (permalink)  
Antiguo 27/04/2012, 21:14
 
Fecha de Ingreso: febrero-2011
Mensajes: 108
Antigüedad: 13 años, 9 meses
Puntos: 4
Respuesta: problema con enteros u caracteres

Gracias sam90, ahora he entendido lo que hace ese famoso while!!!!
  #12 (permalink)  
Antiguo 28/04/2012, 05:42
 
Fecha de Ingreso: abril-2010
Ubicación: Rosario
Mensajes: 1.850
Antigüedad: 14 años, 7 meses
Puntos: 228
Respuesta: problema con enteros u caracteres

Tienes que saber que dentro de las condiciones del while tambien pueden suceder cosas. No es un simple predicado logico. Se ejecutan funciones 1ue pueden alterar el estado de variables.

i=0;
while( c[i++] != '\0');

Esto lee el tamaño de una cadena por ejemplo. Equivale a:

while(c[i] != '\0') i++;

Saludos

Etiquetas: caracteres, enteros, funcion, int, programa, variables
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 12:33.