W3docs

Saisie utilisateur en Java avec Scanner

Lisez les entrées console en Java avec la classe Scanner — nextInt, nextDouble, nextLine et validation des saisies.

Pour la plupart des programmes débutants, le moyen le plus simple de lire les entrées au clavier est java.util.Scanner. Il encapsule System.in (le flux d'entrée standard) et vous offre des méthodes comme nextInt, nextDouble et nextLine. Ce chapitre couvre l'API Scanner, le fameux piège « Scanner saute une ligne » et ce vers quoi se tourner quand Scanner ne suffit plus.

Configurer un Scanner

Scanner se trouve dans java.util, vous avez donc besoin d'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 devrait être fermé lorsque vous avez terminé — mais si vous fermez un scanner sur System.in, vous fermez également l'entrée standard pour le reste du programme. Pour les scripts courts, il est acceptable d'omettre close(). Pour le code plus long, utilisez try-with-resources pour les scanners sur des fichiers, mais pas pour System.in.

Les méthodes de lecture

MéthodeLit
nextLine()le reste de la ligne courante (exclut \n)
next()le prochain jeton délimité par des espaces
nextInt()le prochain jeton, interprété comme int
nextLong()…comme long
nextDouble()…comme double
nextBoolean()…comme boolean
hasNext()true si un autre jeton est disponible
hasNextInt()true si le prochain jeton est un int valide
hasNextLine()true si une autre ligne est disponible

Utilisez les variantes hasNext... pour valider l'entrée avant de la consommer.

Une boucle de saisie complète

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 l'utilisateur saisit autre chose qu'un nombre, nextDouble lève une InputMismatchException. Nous verrons comment la gérer ci-dessous.

Le piège classique — nextInt laisse un saut de ligne derrière lui

Après nextInt() ou nextDouble(), le scanner laisse le saut de ligne de fin dans le tampon. Le nextLine() suivant retourne alors une chaîne vide :

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

Deux solutions courantes :

  • Après nextInt() / nextDouble(), appelez in.nextLine() pour ignorer le reste de la ligne.
  • Utilisez nextLine() partout et analysez la chaîne vous-même :
System.out.print("age? ");
int age = Integer.parseInt(in.nextLine().trim());

Le second style est plus propre dès que vous commencez à gérer la validation.

Valider avec 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);

Lire jusqu'à la fin de fichier

Un schéma courant de traitement par lot — lire jusqu'à ce que l'utilisateur tape Ctrl+D (Linux/macOS) ou Ctrl+Z puis Entrée (Windows) :

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

BufferedReader — quand Scanner n'est pas assez rapide

Pour la programmation compétitive ou partout où vous lisez des dizaines de milliers de lignes, BufferedReader est nettement plus rapide 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());

C'est un peu plus de code, mais un gain de vitesse de 10 à 20× est courant.

System.console() — sessions interactives uniquement

Quand le programme est attaché à un vrai terminal, System.console() retourne un objet Console avec readLine et readPassword (qui n'affiche pas les caractères) :

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() retourne null quand le programme s'exécute via un IDE qui redirige stdin, donc ne vous fiez pas à lui pour les entrées générales.

Une démonstration

Le code exécutable ci-dessous utilise System.in. L'environnement d'exécution ne fournit pas d'entrée interactive, donc cette version lit depuis une chaîne fixe — proche de l'utilisation normale de Scanner :

java— editable, runs on the server

Et ensuite

La partie 2 se termine ici. La partie suivante, Flux de contrôle, commence avec Java if, else et else if et continue avec switch et les boucles qui pilotent la plupart de la logique des programmes.

Pratique

Pratique
Après avoir appelé scanner.nextInt(), pourquoi un scanner.nextLine() suivant retourne-t-il souvent une chaîne vide ?
Après avoir appelé scanner.nextInt(), pourquoi un scanner.nextLine() suivant retourne-t-il souvent une chaîne vide ?
Was this page helpful?