W3docs

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
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 name

Duas correções comuns:

  • Após nextInt() / nextDouble(), chame in.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:

java— editable, runs on the server

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.

Prática

Prática
Após chamar scanner.nextInt(), por que um scanner.nextLine() subsequente frequentemente retorna uma string vazia?
Após chamar scanner.nextInt(), por que um scanner.nextLine() subsequente frequentemente retorna uma string vazia?
Was this page helpful?