CHAPITRE 2.3

Entrées utilisateur

Lire des données saisies par l'utilisateur avec la classe Scanner
Dans cette section, vous allez apprendre à interagir avec l'utilisateur en lisant des données qu'il saisit au clavier. La classe Scanner est l'outil principal en Java pour lire des entrées depuis la console. Vous découvrirez comment l'utiliser pour lire différents types de données : texte, nombres entiers, nombres décimaux, etc. Cette compétence est essentielle pour créer des programmes interactifs.

2.3Entrées utilisateur

2.3.1 – Utilisation de la classe Scanner

La classe Scanner fait partie du package java.util et permet de lire des données depuis différentes sources, notamment depuis la console (entrée standard). C'est l'outil le plus couramment utilisé pour créer des programmes interactifs en Java.

📦 Import de la classe Scanner

Avant d'utiliser Scanner, vous devez l'importer en haut de votre fichier :

Import de Scanner :
import java.util.Scanner;
Où placer l'import : Tout en haut du fichier, avant la déclaration de la classe.

🔧 Création d'un objet Scanner

Pour utiliser Scanner, vous devez créer un objet Scanner. Pour lire depuis la console, utilisez System.in :

Création d'un Scanner :
import java.util.Scanner;

public class ExempleScanner {
    public static void main(String[] args) {
        // Créer un objet Scanner pour lire depuis la console
        Scanner scanner = new Scanner(System.in);
        
        // Utiliser le scanner...
        
        // Important : fermer le scanner à la fin
        scanner.close();
    }
}
Important : Il est recommandé de fermer le Scanner avec scanner.close() à la fin de votre programme pour libérer les ressources. Cependant, si vous fermez System.in, vous ne pourrez plus lire depuis la console dans le reste du programme.

📖 Méthodes de lecture de base

Scanner offre plusieurs méthodes pour lire différents types de données :

Méthode Type retourné Description Exemple
nextLine() String Lit une ligne complète (jusqu'au retour à la ligne) String ligne = scanner.nextLine();
next() String Lit le prochain mot (jusqu'à un espace) String mot = scanner.next();
nextInt() int Lit un nombre entier int nombre = scanner.nextInt();
nextDouble() double Lit un nombre décimal double prix = scanner.nextDouble();
nextFloat() float Lit un nombre décimal (précision simple) float valeur = scanner.nextFloat();
nextBoolean() boolean Lit un booléen (true ou false) boolean actif = scanner.nextBoolean();

💡 Exemple simple : Programme interactif

Voici un exemple complet qui utilise Scanner pour créer un programme interactif :

Exemple : Programme de salutation
import java.util.Scanner;

public class Salutation {
    public static void main(String[] args) {
        // Créer un Scanner
        Scanner scanner = new Scanner(System.in);
        
        // Demander le nom
        System.out.print("Quel est votre nom ? ");
        String nom = scanner.nextLine();
        
        // Afficher un message personnalisé
        System.out.println("Bonjour, " + nom + " ! Bienvenue en Java !");
        
        // Fermer le Scanner
        scanner.close();
    }
}
Exécution :
Quel est votre nom ? Jean
Bonjour, Jean ! Bienvenue en Java !

⚠️ Différence entre next() et nextLine()

Il est important de comprendre la différence entre next() et nextLine() :

next() : Lit un mot

  • Lit jusqu'au prochain espace, tabulation ou retour à la ligne
  • Ignore les espaces avant le mot
  • Ne lit pas le caractère de fin de ligne

nextLine() : Lit une ligne complète

  • Lit toute la ligne jusqu'au retour à la ligne
  • Peut contenir des espaces
  • Consomme le caractère de fin de ligne
Exemple illustrant la différence :
Scanner scanner = new Scanner(System.in);

System.out.print("Entrez votre prénom et nom : ");
String prenom = scanner.next();      // Lit seulement "Jean"
String nom = scanner.next();         // Lit "Dupont"

// Si l'utilisateur entre "Jean Dupont"
// prenom = "Jean"
// nom = "Dupont"

// Avec nextLine() :
System.out.print("Entrez votre nom complet : ");
String nomComplet = scanner.nextLine();  // Lit "Jean Dupont" en entier

🐛 Problème courant : nextInt() suivi de nextLine()

Un problème fréquent survient quand vous utilisez nextInt() (ou nextDouble()) suivi de nextLine() :

Le problème :
Scanner scanner = new Scanner(System.in);

System.out.print("Entrez votre âge : ");
int age = scanner.nextInt();  // Lit 25, mais laisse le '\n' dans le buffer

System.out.print("Entrez votre nom : ");
String nom = scanner.nextLine();  // Lit immédiatement une ligne vide !

// Le nom sera vide car nextLine() lit le '\n' restant
Solution : Ajoutez un scanner.nextLine() supplémentaire pour consommer le retour à la ligne :
int age = scanner.nextInt();
scanner.nextLine();  // Consomme le '\n' restant

String nom = scanner.nextLine();  // Maintenant ça fonctionne !

✅ Vérifier si des données sont disponibles

Vous pouvez vérifier si des données sont disponibles avant de les lire :

Méthodes de vérification :
Scanner scanner = new Scanner(System.in);

// Vérifier s'il y a une ligne suivante
if (scanner.hasNextLine()) {
    String ligne = scanner.nextLine();
}

// Vérifier s'il y a un entier suivant
if (scanner.hasNextInt()) {
    int nombre = scanner.nextInt();
}

// Vérifier s'il y a un double suivant
if (scanner.hasNextDouble()) {
    double valeur = scanner.nextDouble();
}

💡 Points clés à retenir

  • Import : import java.util.Scanner; en haut du fichier
  • Création : Scanner scanner = new Scanner(System.in);
  • nextLine() : Lit une ligne complète (avec espaces)
  • next() : Lit un mot (jusqu'à un espace)
  • nextInt() : Lit un entier
  • nextDouble() : Lit un nombre décimal
  • Problème courant : Après nextInt(), ajoutez nextLine() pour consommer le '\n'
  • Fermeture : scanner.close() à la fin (optionnel mais recommandé)
Conseil pratique : Pour éviter les problèmes avec nextInt() suivi de nextLine(), vous pouvez toujours utiliser nextLine() pour lire une chaîne, puis la convertir en nombre avec Integer.parseInt() ou Double.parseDouble().

2.3.2 – Lecture de différents types de données

Dans cette section, nous allons voir en détail comment lire différents types de données avec Scanner : entiers, décimaux, caractères, booléens, et chaînes de caractères. Vous apprendrez également à gérer les erreurs et à créer des programmes robustes.

🔢 Lecture de nombres entiers

Lecture d'un int

Exemple : Lire un entier
import java.util.Scanner;

public class LectureEntier {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        System.out.print("Entrez votre âge : ");
        int age = scanner.nextInt();
        
        System.out.println("Vous avez " + age + " ans.");
        
        scanner.close();
    }
}

Lecture d'un long

Exemple : Lire un long
Scanner scanner = new Scanner(System.in);

System.out.print("Entrez un grand nombre : ");
long grandNombre = scanner.nextLong();

System.out.println("Vous avez entré : " + grandNombre);

Gestion des erreurs

Si l'utilisateur entre une valeur invalide, nextInt() lèvera une exception. Pour gérer cela proprement :

Exemple avec gestion d'erreur :
Scanner scanner = new Scanner(System.in);

System.out.print("Entrez un nombre : ");
if (scanner.hasNextInt()) {
    int nombre = scanner.nextInt();
    System.out.println("Nombre valide : " + nombre);
} else {
    System.out.println("Erreur : ce n'est pas un nombre entier valide !");
    scanner.next();  // Consomme la valeur invalide
}

scanner.close();

🔢 Lecture de nombres décimaux

Lecture d'un double

Exemple : Lire un nombre décimal
import java.util.Scanner;

public class LectureDecimal {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        System.out.print("Entrez un prix : ");
        double prix = scanner.nextDouble();
        
        System.out.println("Le prix est : " + prix + " €");
        
        scanner.close();
    }
}
Note : Vous pouvez entrer le nombre avec un point 19.99 ou une virgule 19,99 selon la configuration locale.

Lecture d'un float

Exemple : Lire un float
Scanner scanner = new Scanner(System.in);

System.out.print("Entrez une température : ");
float temperature = scanner.nextFloat();

System.out.println("Température : " + temperature + " °C");

🔤 Lecture de texte

Lecture d'une ligne complète

Exemple : Lire une ligne
import java.util.Scanner;

public class LectureTexte {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        System.out.print("Entrez votre nom complet : ");
        String nomComplet = scanner.nextLine();
        
        System.out.println("Bonjour, " + nomComplet + " !");
        
        scanner.close();
    }
}

Lecture d'un mot

Exemple : Lire un mot
Scanner scanner = new Scanner(System.in);

System.out.print("Entrez votre prénom : ");
String prenom = scanner.next();  // Lit seulement jusqu'au premier espace

System.out.println("Prénom : " + prenom);

✅ Lecture d'un booléen

Exemple : Lire un booléen
import java.util.Scanner;

public class LectureBooleen {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        System.out.print("Êtes-vous actif ? (true/false) : ");
        boolean estActif = scanner.nextBoolean();
        
        if (estActif) {
            System.out.println("Vous êtes actif !");
        } else {
            System.out.println("Vous n'êtes pas actif.");
        }
        
        scanner.close();
    }
}
Note : L'utilisateur doit entrer exactement true ou false (sensible à la casse).

📝 Exemple complet : Formulaire interactif

Voici un exemple complet qui combine la lecture de différents types de données :

Exemple : Formulaire de saisie
import java.util.Scanner;

public class Formulaire {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Lire le nom
        System.out.print("Entrez votre nom : ");
        String nom = scanner.nextLine();
        
        // Lire l'âge
        System.out.print("Entrez votre âge : ");
        int age = scanner.nextInt();
        scanner.nextLine();  // Consommer le '\n' restant
        
        // Lire la ville
        System.out.print("Entrez votre ville : ");
        String ville = scanner.nextLine();
        
        // Lire le salaire
        System.out.print("Entrez votre salaire : ");
        double salaire = scanner.nextDouble();
        scanner.nextLine();  // Consommer le '\n' restant
        
        // Afficher les informations
        System.out.println("\n=== Informations ===");
        System.out.println("Nom : " + nom);
        System.out.println("Âge : " + age + " ans");
        System.out.println("Ville : " + ville);
        System.out.println("Salaire : " + salaire + " €");
        
        scanner.close();
    }
}
Exécution :
Entrez votre nom : Jean Dupont
Entrez votre âge : 30
Entrez votre ville : Paris
Entrez votre salaire : 3500.50

=== Informations ===
Nom : Jean Dupont
Âge : 30 ans
Ville : Paris
Salaire : 3500.5 €

🔄 Conversion de String en nombre

Parfois, il est préférable de lire une ligne complète puis de la convertir en nombre. Cela évite les problèmes avec nextInt() suivi de nextLine() :

Exemple : Conversion String → int
Scanner scanner = new Scanner(System.in);

System.out.print("Entrez votre âge : ");
String ageStr = scanner.nextLine();  // Lit comme String
int age = Integer.parseInt(ageStr);  // Convertit en int

System.out.println("Vous avez " + age + " ans.");
Exemple : Conversion String → double
Scanner scanner = new Scanner(System.in);

System.out.print("Entrez un prix : ");
String prixStr = scanner.nextLine();  // Lit comme String
double prix = Double.parseDouble(prixStr);  // Convertit en double

System.out.println("Prix : " + prix + " €");
Gestion d'erreur : Integer.parseInt() et Double.parseDouble() lèvent une exception si la chaîne n'est pas un nombre valide. Pour gérer cela, utilisez un bloc try-catch (nous verrons cela dans le chapitre sur les exceptions).

🎯 Bonnes pratiques

  • Messages clairs : Utilisez System.out.print() (sans retour à la ligne) pour les questions, afin que la saisie soit sur la même ligne
  • Gestion des erreurs : Vérifiez toujours si les données sont valides avec hasNextInt(), hasNextDouble(), etc.
  • Consommer les retours à la ligne : Après nextInt() ou nextDouble(), ajoutez nextLine() pour éviter les problèmes
  • Alternative : Utilisez nextLine() + conversion pour plus de contrôle
  • Fermeture : Fermez le Scanner avec close() à la fin

💡 Points clés à retenir

  • nextInt() : Lit un entier, mais laisse '\n' dans le buffer
  • nextDouble() : Lit un décimal, mais laisse '\n' dans le buffer
  • nextLine() : Lit une ligne complète, consomme le '\n'
  • next() : Lit un mot (jusqu'à un espace)
  • nextBoolean() : Lit true ou false
  • Problème courant : Après nextInt()/nextDouble(), ajoutez nextLine() pour consommer '\n'
  • Alternative : Utilisez nextLine() + Integer.parseInt() ou Double.parseDouble()
  • Vérification : Utilisez hasNextInt(), hasNextDouble() pour vérifier avant de lire
Conseil pratique : Pour débuter, privilégiez l'utilisation de nextLine() pour tout lire comme String, puis convertissez en nombre si nécessaire. Cette approche évite la plupart des problèmes courants avec Scanner.