Error nextInt() seguido de nextLine() en Java

nextInt() seguido de nextLine() provoca error

El pasado año, en la clase de Programación de primero de Desarrollo de Aplicaciones Web, en concreto, haciendo algunos ejercicios de Java nos encontramos con un error que surgía tras utilizar los métodos nextInt(), y a continuación, nextLine() de la clase Scanner.

Adjunto dos capturas para explicar este problema.

Ejemplo de uso en un programa de los métodos nextInt() y nextLine() de la clase Scanner en Java. En este caso funciona correctamente.

En este ejemplo, podemos observar, como el código funciona correctamente. Nos pide que introduzcamos nuestro nombre, posteriormente la edad e imprime el resultado correcto.

En esta segunda captura, veremos que en la consola no funciona todo correctamente.

Ejemplo de uso en un programa de los métodos nextInt() y nextLine() de la clase Scanner en Java. En este caso obtenemos un error.

Como vemos, en este caso, solicitamos primero que se introduzca la edad, al hacerlo y pulsar <<Enter>>, vemos como automáticamente, “Introduce tu nombre” es saltado, y en el resultado final obtenemos la incongruencia, ya que no se ha guardado ningún nombre.

¿Qué ha provocado este error?

Si analizamos ambos programas, la única diferencia que podemos encontrar es el orden en el que se introducen los campos. En el primero, hemos introducido primero la cadena de texto, y posteriormente hemos solicitado el entero.

Sin embargo, en el segundo caso, hemos cambiado el orden de la petición de datos. En primer lugar, se ha pedido el entero y posteriormente era el turno de la cadena.

¿Por qué ha sucedido este error?

Ya hemos comprobado que sucede cuando primero se solicita el dato entero, y posteriormente, la cadena. Pero ¿por qué sucede?

El motivo por el que esto pasa, es porque el método nextInt() de la clase Scanner no funciona como esperamos. Exactamente, nos sirve para capturar datos enteros por teclado, pero sólo captura ese dato.

Eso quiere decir, que cuando nosotros introducimos por teclado la edad, introducimos el número, pero también pulsamos la tecla enter (retorno de carro o salto de línea), por tanto el valor que en ese momento tenemos en el buffer es 35/n de lo cual, la función nextInt() captura lo que haya hasta el primer carácter no numérico.

De este modo, guardamos en la variable número el valor 35, pero en el búffer sigue quedando /n

Cuando se hace la llamada para insertar valor en la variable cadena, nextInt(), realiza la lectura de todo lo que haya hasta el siguiente salto de línea (/n), que, como diría un antiguo profesor mío, “oh, sorpresa”, es lo que hay almacenado en buffer.

Por este motivo, el programa pasa automáticamente de esta acción asignando un valor vacío a la variable cadena.

¿Cómo podemos solucionarlo?

En este caso, el problema sería muy fácil de solucionar, sólo deberíamos pedir los datos en el orden anterior y, como hemos visto, funcionaría. Pero imaginemos que tenemos un formulario con diferentes preguntas y en ellas, el orden es muy importante.

Solución 1. nextLine() adicional.

Para evitar el error por el uso de nextInt() y posteriormente de nextLine() por los datos en el buffer mencionado en el punto anterior la solución más sencilla sería utilizar utilizar un nextLine() intermedio. Es decir:

package pruebas;

import java.util.Scanner;

public class NextIntNextLine {

	public static void main(String[] args) {
		Scanner s = new Scanner(System.in);
		
		String cadena;
		int numero;
		
		System.out.println("Introduce tu edad: ");
		numero = s.nextInt(); s.nextLine();
		System.out.println("Introduce tu nombre: ");
		cadena = s.nextLine();
		
		System.out.println("Mi nombre es: " + cadena + " y mi edad: " + numero);
		
		s.close();
		
	}
}

Observa, como en la línea 14, hemos introducido adicionalmente s.nextLine();

La finalidad de esta inclusión, es que nos sirva para vaciar el buffer que pueda quedar tras utilizar el método nextInt().

En algunos foros, se recomienda utilizar siempre esta sentencia justo después de utilizar el método nextInt(), personalmente no creo que sea necesario, pero sí que es preciso que estemos muy atentos si se produce esta casuística.

Ejemplo de uso en un programa de los métodos nextInt() y nextLine() de la clase Scanner en Java. Error solucionado con nextLine() adicional.

Solución 2. Utilizar sólo nextLine() y realizar conversión de tipo.

Esta segunda solución resulta un poco más engorrosa bajo mi punto de vista. Para ello el objetivo es no utilizar nextInt(), sino hacerlo siempre con nextLine() y posteriormente hacer una conversión al dato.

package pruebas;

import java.util.Scanner;

public class NextIntNextLine {

	public static void main(String[] args) {
		Scanner s = new Scanner(System.in);
		
		String cadena;
		int numero;
		
		System.out.println("Introduce tu edad: ");
		numero = Integer.parseInt(s.nextLine());
		System.out.println("Introduce tu nombre: ");
		cadena = s.nextLine();
		
		System.out.println("Mi nombre es: " + cadena + " y mi edad: " + numero);
		
		s.close();
		
	}
}

Al igual que en la primera solución, esta alternativa se arregla modificando tan sólo la línea 14, que como vemos, quedaría numero = Integer.parseInt(s.nextLine());

De este modo, siempre leemos la línea completa hasta llegar al salto de línea, y en el caso de estar esperando un número entero, lo capturamos y lo convertimos a este formato.

Ejemplo de uso en un programa de los métodos nextInt() y nextLine() de la clase Scanner en Java. Error solucionado mediante casting.

Como hemos visto, el error que se produce tras utilizar nextInt() seguido de nextLine(), tiene dos soluciones muy sencillas cuando entendemos por qué se produce. Personalmente me gusta más la primera, ¿Con cuál te quedas tú?

Offtopic

Además de este breve artículo para hablar sobre uno de los problemas habituales cuando estamos empezando a programar, en este blog podrás encontrar material para la iniciación en el programación en Java. Si puede resultar de tu interés tienes a tu disposición apuntes de iniciación y una serie de ejercicios resueltos que te podrán ayudar.

Este material recoge un amplio repaso de las actividades llevadas a cacabo durante el curso 2019/2020 en la clase de programación de 1º DAW del I.E.S. Gran Capitán de Córdoba.

La asignatura fue impartida por Rafael del Castillo y siguiendo como guía principal el libro Aprende Java con Ejercicios de Luis José Sánchez, el cual recomiendo desde aquí para todo aquel que quiera aprender desde 0 en la programación con Java.