sábado, 16 de febrero de 2019

Problema con nextInt() y las Excepciones.

Cuando hacemos una lectura de un número entero con el método nextInt() de un objeto Scanner, puede saltar la excepción InputMismatchException que si no la gestionamos bien en un bucle puede resultar en bucle infinito. Un ejemplo:

        boolean comprueba;
        Scanner sc = new Scanner(System.in);
        int numero;
        do{
            try{
                comprueba = false;
                System.out.println("Introduce un número entero");
                
                numero=sc.nextInt();
              
                 
            }catch(java.util.InputMismatchException e){
             
                System.out.println("Error, inténtalo de nuevo.");
                comprueba=true;
                 
            }
        }while(comprueba); 

Si ejecutas este código y metes una letra en lugar de un número verás dicho bucle infinito. Esto sucede porque el nextInt trata de leer algo que no puede y lanza la excepción, ¡¡Pero no llega a leer el dato y por tanto dicho dato inválido queda en el buffer de teclado!! Esto conlleva que a la siguiente vuelta del bucle vuelva a leer el dato incorrecto pues sigue a la espera de ser leído. Solución: muy simple, meter un nextLine pero en el  catch de forma que se recoja ese dato inválido.
Algo así:

        boolean comprueba;
        Scanner sc = new Scanner(System.in);
        int numero;
        do{
            try{
                comprueba = false;
                System.out.println("Introduce un número entero");
                
                numero=sc.nextInt();
              
                 
            }catch(java.util.InputMismatchException e){
             
                System.out.println("Error, inténtalo de nuevo.");
                comprueba=true;
                sc.nextLine(); //La solución es esta.
                 
            }
        }while(comprueba); 

Lo que se comenta anteriormente es válido también para nextDouble y otros métodos next.