W3docs

Entrada de usuario en Java con Scanner

Lee entrada desde la consola en Java con la clase Scanner — nextInt, nextDouble, nextLine y validación de entrada.

Para la mayoría de los programas para principiantes, la forma más sencilla de leer entrada desde el teclado es java.util.Scanner. Envuelve System.in (el flujo de entrada estándar) y te proporciona métodos como nextInt, nextDouble y nextLine. Este capítulo cubre la API de Scanner, el famoso problema de "Scanner omite una línea" y qué usar cuando Scanner deja de ser suficiente.

Configurar un Scanner

Scanner vive en java.util, así que necesitas un import:

import java.util.Scanner;

public class Greeter {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.print("What is your name? ");
        String name = in.nextLine();
        System.out.println("Hello, " + name + "!");
    }
}

Scanner debería cerrarse cuando termines de usarlo — pero si cierras un scanner sobre System.in, también cierras la entrada estándar para el resto del programa. En scripts cortos, está bien omitir close(). En código más largo, usa try-with-resources para scanners sobre archivos, pero no para System.in.

Los métodos de lectura

MétodoLee
nextLine()el resto de la línea actual (excluye \n)
next()el siguiente token delimitado por espacios en blanco
nextInt()el siguiente token, interpretado como int
nextLong()…como long
nextDouble()…como double
nextBoolean()…como boolean
hasNext()true si hay otro token disponible
hasNextInt()true si el siguiente token es un int válido
hasNextLine()true si hay otra línea disponible

Usa las variantes hasNext... para validar la entrada antes de consumirla.

Un bucle de solicitud completo

import java.util.Scanner;

public class Calculator {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        System.out.print("First number: ");
        double a = in.nextDouble();

        System.out.print("Second number: ");
        double b = in.nextDouble();

        System.out.println("Sum: " + (a + b));
    }
}

Si el usuario escribe algo que no es un número, nextDouble lanza InputMismatchException. Cubriremos cómo manejar eso más abajo.

El problema clásico — nextInt deja una nueva línea pendiente

Después de nextInt() o nextDouble(), el scanner deja la nueva línea al final en el búfer. El siguiente nextLine() devuelve entonces una cadena vacía:

System.out.print("age? ");
int age = in.nextInt();        // user types "30" then Enter

System.out.print("name? ");
String name = in.nextLine();   // returns "" — the leftover newline
String name2 = in.nextLine();  // returns the typed name

Dos soluciones comunes:

  • Después de nextInt() / nextDouble(), llama a in.nextLine() para descartar el resto de la línea.
  • Usa nextLine() en todas partes y analiza la cadena tú mismo:
System.out.print("age? ");
int age = Integer.parseInt(in.nextLine().trim());

El segundo estilo es más limpio una vez que empiezas a manejar validaciones.

Validar con hasNext...

Scanner in = new Scanner(System.in);
System.out.print("Enter a number: ");

while (!in.hasNextInt()) {
    System.out.print("That isn't an integer. Try again: ");
    in.next();   // discard the bad token
}
int value = in.nextInt();
System.out.println("You entered: " + value);

Leer hasta EOF

Un patrón habitual de procesamiento por lotes — leer hasta que el usuario presione Ctrl+D (Linux/macOS) o Ctrl+Z y luego Enter (Windows):

Scanner in = new Scanner(System.in);
int total = 0;
while (in.hasNextInt()) {
    total += in.nextInt();
}
System.out.println("Total: " + total);

BufferedReader — cuando Scanner no es suficientemente rápido

Para programación competitiva o en cualquier lugar donde leas decenas de miles de líneas, BufferedReader es significativamente más rápido que Scanner:

import java.io.BufferedReader;
import java.io.InputStreamReader;

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = br.readLine();
int n = Integer.parseInt(line.trim());

Requiere un poco más de código, pero una mejora de velocidad de 10 a 20 veces es habitual.

System.console() — solo para sesiones interactivas

Cuando el programa está conectado a un terminal real, System.console() devuelve un objeto Console con readLine y readPassword (que no muestra los caracteres en pantalla):

java.io.Console c = System.console();
if (c != null) {
    String user = c.readLine("Username: ");
    char[] pass = c.readPassword("Password: ");
    // ... use pass ...
    java.util.Arrays.fill(pass, ' ');  // zero out the password buffer
}

System.console() devuelve null cuando el programa se ejecuta a través de un IDE que redirige stdin, así que no dependas de él para la entrada general.

Una demostración

El código ejecutable a continuación usa System.in. El ejecutor no proporciona entrada interactiva, por lo que esta versión lee desde una cadena fija — muy parecido a cómo se usa Scanner normalmente:

java— editable, runs on the server

Qué sigue

La parte 2 termina aquí. La siguiente parte, Control de flujo, comienza con Java if, else y else if y continúa con switch y los bucles que impulsan la mayor parte de la lógica de los programas.

Práctica

Práctica
After calling scanner.nextInt(), why does a following scanner.nextLine() often return an empty string?
After calling scanner.nextInt(), why does a following scanner.nextLine() often return an empty string?
Was this page helpful?