Tabla de Contenidos
Clase Scanner
La clase Scanner está disponible desde Java 5, y ofrece métodos para leer datos introducidos por el usuario desde la entrada standard (teclado).
A diferencia de la clase String, la clase Scanner se encuentra en el paquete java.util
.
Importar la clase Scanner
Como hemos dicho, para poder usar la clase Scanner debemos importarla desde su paquete. La sentencia import
siempre debe ir al principio del código, después de la sentencia package
:
package nombrePaquete; //si mi clase está dentro de un paquete import java.util.Scanner;
Crear un objeto Scanner
Para poder usarla debemos crear un objeto de la clase Scanner. Lo asociamos a la entrada standard:
Scanner input = new Scanner(System.in); //Cerrar siempre el scanner input.close();
IMPORTANTE: El método close()
no cierra el Scanner, sino que cierra el flujo de entrada System.in
. Cualquier lectura posterior desde ese flujo (System.in), lanzará una excepción.
Tipos de flujos de entrada
System.in
representa la entrada standard, el teclado, del mismo modo que System.out
representa la salida standard, la consola.
Pero Scanner también puede leer desde un String
, o desde un fichero de texto, objeto File
.
Leer tipos de datos
La clase Scanner tiene métodos para leer directamente los siguientes tipos de datos:
String
, short
, byte
, int
, float
, long
, double
y boolean
.
int entero = input.nextInt(); boolean booleano = input.nextBoolean(); double real = input.nextDouble(); String cadena = input.nextLine(); //Lee caracteres hasta encontrar un intro
El método nextLine()
lee todos los caracteres que haya en el buffer de entrada, hasta encontrar un carácter de intro
.
No podemos leer un char
, pero podemos leerlo como String y coger el primer caracter.
char caracter = input.nextLine().charAt(0); //Que es lo mismo que: String cadena = input.nextLine(); char caracter = cadena.charAt(0);
Con el método next()
podemos obtener un String con la siguiente palabra, separada por espacios. No se recomienda su uso para leer Strings.
//Introducimos por teclado el texto -> "Cadena de 4 palabras" String palabra1 = input.next(); -> obtengo "Cadena" String palabra2 = input.next(); -> obtengo "de" String cadena = input.nextLine(); -> obtengo "4 palabras";
Funcionamiento interno
De forma resumida, cuando introducimos texto por teclado, el objeto Scanner divide la cadena de texto completa, en elementos llamados tokens
y los guarda en su buffer de lectura ó entrada
.
El caracter por defecto para separar los tokens es el ' ' (espacio en blanco).
Ejemplo:
- Introduzco la cadena
12 20.001 Lucas w
y pulso intro. - Scanner crea la siguiente lista de tokens:
12
20.001
Lucas
w
A continuación puedo acceder a esos tokens
almacenados en el buffer de lectura, a través de los distintos métodos.
//Introduzco por teclado una cadena formada por 5 "tokens" //Por ejemplo la cadena: "4 o 5 palabras cortas" int num = input.nextInt(); //leo el "4" como tipo int String cadena1 = next(); //leo la "o" como tipo String String cadena2 = next(); //leo el "5" como tipo String String cadena3 = nextLine(); //leo hasta encontrar un intro: "palabras cortas"
Limpiar buffer de lectura
Cada vez que introducimos datos por teclado terminamos presionando intro
.
Scanner guarda en el buffer de entrada todos los caracteres introducidos, incluido la tecla intro
.
Buffer de entrada al introducir el numero 53:
// Estado del buffer de entrada: "53\n" -> \n representa la tecla enter int numero = input.nextInt(); //Estado del buffer de entrada después de leer el int "\n" String cadena = input.nextLine(); //Leerá hasta encontrar el enter, y obtenemos una cadena vacía "".
Siempre que vaya a leer un String después de haber leido un número, debemos limpiar el buffer de entrada antes de leer el String, llamando al método:
input.nextLine();
Comprobar estado del buffer
Scanner
también contiene algunos métodos para comprobar si quedan datos en el flujo de entrada (buffer). Esto es realmente interesante cuando el flujo de entrada son datos contenidos en un fichero, y desconocemos el número de lineas.
Los siguientes métodos devuelven true
mientras queden datos en el flujo de entrada:
Metodo | Función |
---|---|
hasNextInt() | Comprueba si quedan enteros |
hasNextLine() | Comprueba si quedan Strings |
hasNextFloat() | Comprueba si quedan valores float |
hasNextDouble() | Comprueba si quedan valores double |
hasNextShort() | Comprueba si quedan enteros cortos |
hasNext() | Comprueba si quedan palabras (tokens) |
hasNextBoolean() | Comprueba si quedan valores booleanos |
Podemos usarlo con un bucle while, para leer mientras quedan valores.
while(input.hasNextLine(){ String cadena = input.nextLine(); //proceso datos leidos }
Leer número de coma flotante con distinta notación
Los lenguajes de programación usan por defecto la notación americana a la hora de trabajar con números decimales:
float decimalFloat = 3.13F; //literal de float double decimalDouble = 4.345; //literal de double
Pero a la hora de leer, Scanner accede a la configuración regional de nuestro sistema. En España se usa la notación francesa (34,6
).
Si queremos que nuestro Scanner lea los decimales con un .
en lugar de con una ,
, debemos indicarle que usamos la configuración local americana.
System.out.println(input.locale()); input.setLocale(Locale.US);
© 2024 Fernando Valdeón