Herramientas de usuario

Herramientas del sitio


bloque2:scanner

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);


© 2020 Fernando Valdeón

bloque2/scanner.txt · Última modificación: 08/10/2019 15:00 por Fernando Valdeón