W3docs

Input utente in Java con Scanner

Leggi input dalla console in Java con la classe Scanner — nextInt, nextDouble, nextLine e validazione dell'input.

Per la maggior parte dei programmi per principianti, il modo più semplice per leggere input dalla tastiera è java.util.Scanner. Esso racchiude System.in (il flusso di input standard) e fornisce metodi come nextInt, nextDouble e nextLine. Questo capitolo tratta le API di Scanner, il famoso problema del "Scanner che salta una riga" e le alternative da considerare quando Scanner non è più adeguato.

Configurare uno Scanner

Scanner si trova in java.util, quindi è necessario 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 dovrebbe essere chiuso quando non è più necessario — ma se si chiude uno scanner su System.in, si chiude anche l'input standard per il resto del programma. Per script brevi va bene omettere close(). Per codice più lungo, usa try-with-resources per gli scanner su file, ma non per System.in.

I metodi di lettura

MetodoLegge
nextLine()il resto della riga corrente (esclude \n)
next()il prossimo token delimitato da spazi bianchi
nextInt()il prossimo token, interpretato come int
nextLong()…come long
nextDouble()…come double
nextBoolean()…come boolean
hasNext()true se è disponibile un altro token
hasNextInt()true se il prossimo token è un intero valido
hasNextLine()true se è disponibile un'altra riga

Usa le varianti hasNext... per validare l'input prima di leggerlo.

Un ciclo di richiesta 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 l'utente digita un valore non numerico, nextDouble lancia un'eccezione InputMismatchException. Vedremo come gestirla di seguito.

Il problema classico — nextInt lascia un a-capo nel buffer

Dopo nextInt() o nextDouble(), lo scanner lascia il carattere di nuova riga nel buffer. La successiva chiamata a nextLine() restituirà quindi una stringa vuota:

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

Due soluzioni comuni:

  • Dopo nextInt() / nextDouble(), chiama in.nextLine() per scartare il resto della riga.
  • Usa nextLine() ovunque e analizza la stringa manualmente:
System.out.print("age? ");
int age = Integer.parseInt(in.nextLine().trim());

Il secondo approccio è più pulito quando si inizia a gestire la validazione.

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

Leggere fino a EOF

Un pattern comune per l'elaborazione batch — leggi finché l'utente non digita Ctrl+D (Linux/macOS) o Ctrl+Z seguito da Invio (Windows):

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

BufferedReader — quando Scanner non è abbastanza veloce

Per la programmazione competitiva o in qualsiasi contesto in cui si leggono decine di migliaia di righe, BufferedReader è significativamente più veloce di 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());

Richiede un po' più di codice, ma un'accelerazione di 10–20× è comune.

System.console() — solo sessioni interattive

Quando il programma è collegato a un terminale reale, System.console() restituisce un oggetto Console con readLine e readPassword (che non mostra i caratteri digitati):

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() restituisce null quando il programma viene eseguito tramite un IDE che reindirizza stdin, quindi non fare affidamento su di esso per l'input generale.

Una dimostrazione

Il codice eseguibile di seguito usa System.in. Il runner non fornisce input interattivo, quindi questa versione legge da una stringa fissa — simile a come viene normalmente utilizzato Scanner:

java— editable, runs on the server

Cosa c'è dopo

La Parte 2 si conclude qui. La parte successiva, Flusso di controllo, inizia con Java if, else e else if e prosegue con switch e i cicli che guidano la maggior parte della logica dei programmi.

Esercitazione

Pratica
Dopo aver chiamato scanner.nextInt(), perché una successiva chiamata a scanner.nextLine() spesso restituisce una stringa vuota?
Dopo aver chiamato scanner.nextInt(), perché una successiva chiamata a scanner.nextLine() spesso restituisce una stringa vuota?
Was this page helpful?