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étodo | Lee |
|---|---|
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 nameDos soluciones comunes:
- Después de
nextInt()/nextDouble(), llama ain.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:
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.