Entrada do Usuário em Java com Scanner
Leia entrada do console em Java com a classe Scanner — nextInt, nextDouble, nextLine e validação de entrada.
Para a maioria dos programas iniciantes, a forma mais simples de ler entrada do teclado é java.util.Scanner. Ele envolve System.in (o fluxo de entrada padrão) e oferece métodos como nextInt, nextDouble e nextLine. Este capítulo cobre a API do Scanner, o famoso problema de "Scanner pular uma linha" e o que usar quando o Scanner deixar de ser suficiente.
Configurando um Scanner
Scanner está em java.util, então você precisa de um 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 deve ser fechado quando você terminar de usá-lo — mas se você fechar um scanner sobre System.in, também fechará a entrada padrão para o restante do programa. Para scripts curtos, tudo bem omitir close(). Para código mais longo, use try-with-resources para scanners sobre arquivos, mas não para System.in.
Os métodos de leitura
| Método | Lê |
|---|---|
nextLine() | o restante da linha atual (exclui \n) |
next() | o próximo token delimitado por espaço em branco |
nextInt() | o próximo token, interpretado como int |
nextLong() | …como long |
nextDouble() | …como double |
nextBoolean() | …como boolean |
hasNext() | true se outro token estiver disponível |
hasNextInt() | true se o próximo token for um int válido |
hasNextLine() | true se outra linha estiver disponível |
Use as variantes hasNext... para validar a entrada antes de consumi-la.
Um laço de prompt 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));
}
}Se o usuário digitar um valor não numérico, nextDouble lança InputMismatchException. Veremos como tratar isso abaixo.
O problema clássico — nextInt deixa uma nova linha para trás
Após nextInt() ou nextDouble(), o scanner deixa a nova linha final no buffer. O próximo nextLine() retorna então uma string vazia:
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 nameDuas correções comuns:
- Após
nextInt()/nextDouble(), chamein.nextLine()para descartar o restante da linha. - Use
nextLine()em todo lugar e analise a string você mesmo:
System.out.print("age? ");
int age = Integer.parseInt(in.nextLine().trim());O segundo estilo é mais limpo quando você começa a lidar com validação.
Validando com 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);Lendo até EOF
Um padrão comum de processamento em lote — leia até o usuário digitar Ctrl+D (Linux/macOS) ou Ctrl+Z e depois Enter (Windows):
Scanner in = new Scanner(System.in);
int total = 0;
while (in.hasNextInt()) {
total += in.nextInt();
}
System.out.println("Total: " + total);BufferedReader — quando o Scanner não é rápido o suficiente
Para programação competitiva ou em qualquer lugar onde se leia dezenas de milhares de linhas, BufferedReader é significativamente mais 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());É um pouco mais de código, mas um aumento de velocidade de 10 a 20 vezes é comum.
System.console() — somente em sessões interativas
Quando o programa está conectado a um terminal real, System.console() retorna um objeto Console com readLine e readPassword (que não ecoa os caracteres):
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() retorna null quando o programa é executado por uma IDE que redireciona stdin, então não dependa dele para entrada geral.
Uma demonstração
O código executável abaixo usa System.in. O executor não fornece entrada interativa, então esta versão lê de uma string fixa — próximo de como o Scanner é normalmente usado:
O que vem a seguir
A Parte 2 termina aqui. A próxima parte, Fluxo de controle, começa com if, else e else if em Java e continua com switch e os laços que impulsionam a maior parte da lógica dos programas.