Saltar al contenido

El Buffer de la clase Scanner.

Para explicar lo que es el buffer de la clase Scanner, vamos a utilizar el último ejemplo de código que utilizamos en en este artículo con una diferencia.

En este caso lo que haremos será pedir al usuario, primero una edad y después un nombre.

package arranque;
/* Importamos todas las clases del 
 * paquete java.util.*/
import java.util.*;
public class ClasePrincipal {
	public static void main(String[] args) {
		
		// Declaro un objeto lectura para leer los datos
	    // introducidos por el usuario.
	    Scanner lectura=new Scanner(System.in);
	    // Variable para almacenar el nombre
	    String miNombre=""; 
	    // Variable para almacenar la edad
	    int edad=0; // 
	    
	    // Pedimos la edad.
	    System.out.println("Escribe tu edad");
	    // Guardamos la edad.
	    edad=lectura.nextInt();
	 
	    // Ahora pedimos el nombre
	    System.out.println("Escribe tu nombre:");
	    // Leemos el nombre y lo almacenamos en miNombre
	    miNombre=lectura.nextLine();
	    // Muestro un mensaje con el nombre y la edad
	    System.out.println("Tu nombre es " + miNombre 
	            + "y tu edad es " + edad + " años.");
	    // Mostramos que finalizó el programa
	    System.out.println("Programa finalizado con éxito."); 
	    // Cerramos el objeto lectura para no consumir rescursos
	    lectura.close();    
	}	    
}

El programa escribe la edad del usuario, pero cuando nos pide el nombre, no podemos escribirlo ya que no se nos permite. El programa continua su ejecución y muestra la frase correspondiente al nombre y a la edad. Además nos dice que el programa finalizo con éxito. Y realmente es así, el programa está bien hecho y no tiene errores, pero…

¿Por qué el no deja introducir el nombre y este aparece en blanco?

Para entender esto vamos a explicar que es un buffer de la clase scanner.

El buffer de entrada de datos de la clase Scanner en java.

El buffer, es una parte de la memoria del ordenador que se reserva para almacenar datos que provienen desde los periféricos de entrada como por ejemplo un teclado. Esto quiere decir que los datos que se teclean hacen el siguiente recorrido.

  • Se escribe un dato y al pulsar ENTER, este se envía a la memoria del ordenador.
  • Un buffer, recibe los datos del usuario. El buffer recibirá por un lado el dato enviado y por otro la pulsación del ENTER en un código Ascii.
  • Una vez que el buffer recibe el dato, lo pasa a la variable correspondiente.

Bien teniendo esta imagen en mente, vamos a desglosar el código.

package ejerciciosSystemIn;
/* Importamos todas las clases del 
 * paquete java.util.*/
import java.util.*;
public class ClasePrincipal {
	public static void main(String[] args) {
		
	    // Declaramos el objeto scanner
	    Scanner lectura=new Scanner(System.in);
	    
	    // Variable para almacenar el nombre
	    String miNombre=""; 
	    
	    // Variable para Almacenar la edad
	    int edad=0;
	    // Ahora pedimos su edad y la guardamos en edad
	    System.out.println("Escribe tu edad:");
	    /* Hasta aquí, declaramos dos variables y les
	     * damos un valor inicial.*/
	    // Pedimos la edad y lógicamente la tecleamos
	    /* Para enviarla a la variable, primero se almacena
	     * en un buffer*/
	}	    
}

¿Qué recibe el buffer en la clase scanner?

El buffer de la clase scanner, va a recibir el dato que el usuario introduzca por teclado una vez que se pulse la tecla ENTER. En ese momento el buffer en nuestro ejemplo, está recibiendo 2 datos.

  • Por un lado el número 25.
  • Y por otro, esta recibiendo un “\n”.

Éste símbolo, \n, para java es considerado un valor tipo String, es decir un texto. Esto quiere decir que:

  • El buffer enviará a la variable numérica el valor 25.
  • Se quedará con el caracter “\n” guardado para él.
edad=lectura.nextInt();
/* Cuando llega a esta instrucción, envia el número 25
 * quedándose con el caracter \n en su interior.*/
	    
/* La ejecución del programa sigue y muestra este mensaje
 * hasta aquí todo bien.*/
 * System.out.println("Escribe tu nombre:");
 * Pero ¿Por qué no se para aquí para teclear el nombre?

Esto es debido a que cuando el enviamos un dato a una variable primero pasa por el buffer y el buffer tiene que estar vacío para poder recibir nuevos datos. En este caso el buffer tiene un caracter “\n” almacenado. Lo que significa que está almacenando un salto de linea provocado por la pulsación del ENTER. Esto para el buffer de java es considerado de tipo de dato String, es decir, un tipo texto. Por ese motivo al invocar al método nextline(); en la variable miNombre almacena un caracter en blanco. Esto es porque está leyendo el salto de línea que esta almacenado en dicho buffer.

/* Y a la hora de mostrar el mensaje, no imprime
	     * la variable nombre porque realmente lo que hay
	     * dentro de esa variable es el símbolo \n */
	    System.out.println("Tu nombre es " + miNombre     
	    		+ " y tu edad es " + edad + " años.");
	    // Mostramos que finalizó el programa
	    System.out.println("Programa finalizado con éxito.");

Una vez almacena el valor en blanco, muestra los dos mensajes que le faltan.

¿Cómo solucionar el problema y limpiar el buffer de la clase scanner?

Para solucionar este problema debemos hacer una limpieza de buffer, antes de pedirle el nombre al usuario. Esto lo hacemos con el método nextLine(); de forma que el código quedaría de la siguiente manera:

package ejerciciosSystemIn;
/* Importamos todas las clases del 
 * paquete java.util.*/
import java.util.*;
public class ClasePrincipal {
	public static void main(String[] args) {
		
	    // Declaramos el objeto scanner
	    Scanner lectura=new Scanner(System.in);
	    // Variable para almacenar el nombre
	    String miNombre=""; 
	   
	    // Variable para almacenar la edad
	    int edad=0; 
	    // Ahora pedimos su edad y la guardamos en edad
	    System.out.println("Escribe tu edad:");
	    // Guardamos el número en la variable.
	    edad=lectura.nextInt();
	    /* Aquí el buffer, una vez almacenada la
	     * edad en la variable edad va a contener
	     * un caracter \n
	     * así que antes de que lea lo que lo que
	     * el usuario vaya a introducir por teclado
	     * debemos hacer una limpieza de buffer
	     * esto lo haremos de la siguiente manera:*/
	    lectura.nextLine();
	    // Una vez limpio el buffer pedimos el nombre
	    System.out.println("Escribe tu nombre:");
	    // Lo leemos y lo almacenamos en la variable miNombre.
	    miNombre=lectura.nextLine();
	    // y ahora si mostramos por pantalla los resultados
	    System.out.println("Tu nombre es " + miNombre 
	            + " y tu edad es " + edad + " años.");
	    // Mostramos que finalizó el programa
	    System.out.println("Programa finalizado con éxito.");
	    // y cerramos el objeto lectura para no consumir recursos
	    lectura.close();
	}	    
}