Scanner inputMismatchException

Fermé
stampia02 Messages postés 95 Date d'inscription samedi 30 juillet 2011 Statut Membre Dernière intervention 13 mai 2017 - 15 avril 2017 à 23:54
KX Messages postés 16760 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 12 février 2025 - 20 avril 2017 à 19:04
Bonjour,

Avec scanner, j'ai un inputMismatchException quand je mais des espace? Comment faire alors ?

Merci

2 réponses

KX Messages postés 16760 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 12 février 2025 3 020
16 avril 2017 à 09:23
Bonjour,

Quel type de données essaies-tu de lire ?
Quelle méthode de Scanner utilises-tu pour la récupérer ?
0
stampia02 Messages postés 95 Date d'inscription samedi 30 juillet 2011 Statut Membre Dernière intervention 13 mai 2017 1
17 avril 2017 à 16:04
Voici mon code

public class TestPersonneAutorisee {
public static Scanner scanner = new Scanner(System.in);
	public static void main(String[] args) {
		PersonneAutorisee liste = new PersonneAutorisee();
		System.out.println("Entrez une nouvelle personne: ");
		System.out.println("Prenom : ");
		String prenom = scanner.next();
		System.out.println("Nom : ");
		String nom = scanner.next();
		System.out.println("Adresse : ");
		String adresse = scanner.next();
		System.out.println("Age : ");
		int age = scanner.nextInt();


J'ai un inputMismatchException à la ligne 13, juste après avoir entrée l'adresse.
0
KX Messages postés 16760 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 12 février 2025 3 020
17 avril 2017 à 16:50
Il y a un piège à utiliser Scanner avec System.in à cause de la touche Entrée.

Il vaut donc mieux faire toujours des scanner.nextLine() et après appliquer une conversion sur le résultat obtenu plutôt que de manipuler les autres méthodes qui n'ont pas toutes le même comportement vis à vis de la touche Entrée.

Exemple :

public static final Scanner scanner = new Scanner(System.in);

public static String nextString() {
    return scanner.nextLine();
}

public static int nextInt() {
    return Integer.parseInt(scanner.nextLine());
}

public static void main(String[] args) {
    PersonneAutorisee liste = new PersonneAutorisee();
    System.out.println("Entrez une nouvelle personne: ");
    System.out.println("Prenom : ");
    String prenom = nextString();
    System.out.println("Nom : ");
    String nom = nextString();
    System.out.println("Adresse : ");
    String adresse = nextString();
    System.out.println("Age : ");
    int age = nextInt();
}

Ce découpage permet également de mieux gérer les cas particuliers, par exemple tu parlais d'accepter les espaces dans la saisie, alors il faut d'abord supprimer ces espaces en trop avant de faire la conversion.

public static int nextInt() {
    return Integer.parseInt(scanner.nextLine().trim());
}

On peut bien sûr aller plus loin et gérer tous les cas d'exception, en particulier si ce qui est saisi n'est pas un nombre, ou alors s'il n'est pas dans un intervalle de valeurs données.

public static int nextInt(Optional<Integer> min, Optional<Integer> max) {
    while (true) {
        try {
            int n = Integer.parseInt(scanner.nextLine().trim());
            if (min.isPresent() && n < min.get())
                throw new ArithmeticException("Number must be greater than or equal to " + min.get());
            if (max.isPresent() && n > max.get())
                throw new ArithmeticException("Number must be less than or equal to " + max.get());
        } catch (RuntimeException e) {
            System.err.println("Wrong int, please retry: " + e);
        }
    }
}

public static int nextInt() {
    return nextInt(Optional.empty(), Optional.empty());
}

public static int nextPositiveInt() {
    return nextInt(Optional.of(0), Optional.empty());
}

public static int nextNegativeInt() {
    return nextInt(Optional.empty(), Optional.of(0));
}

public static String nextString() {
    return scanner.nextLine();
}
0
OmeGaFire_ Messages postés 83 Date d'inscription dimanche 19 juin 2016 Statut Membre Dernière intervention 19 janvier 2018
20 avril 2017 à 02:53
Salut,

Une exception InputMismatchException est lancée quand tu essaie de mettre une valeur dans un type de variable pas prévu à cet effet.
Voici une solution:

public static void main(String[] args) {
PersonneAutorisee liste = new PersonneAutorisee();
System.out.println("Entrez une nouvelle personne: ");
System.out.println("Prenom : ");
String prenom = scanner.nextLine();
System.out.println("Nom : ");
String nom = scanner.nextLine();
System.out.println("Adresse : ");
String adresse = scanner.nextLine();
System.out.println("Age : ");
int age = scanner.nextInt();




Et aussi, petite précision:
-nextLine doit être utilisée pour transformer ton input en string
-nextInt, en int
-next... tu connais la suite
-La méthode "next" ne sert presque à rien.

Bonne journée.
0
KX Messages postés 16760 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 12 février 2025 3 020
Modifié le 20 avril 2017 à 23:47
Bonjour,

La méthode "next" ne sert presque à rien.
Avec la configuration par défaut non, surtout sur System.in
Mais sur un fichier texte ça devient très intéressant en le combinant au useDelimiter, par exemple pour lire un fichier CSV la méthode next() permettra de lire chaque valeur séparée par les points-virgules...

Pour le reste : ATTENTION à ma remarque "les autres méthodes qui n'ont pas toutes le même comportement vis à vis de la touche Entrée"
Parce que nextLine() utilise bien un délimiteur sur les sauts de lignes, mais nextInt() utilise lui un délimiteur sur les espaces, donc il ne consomme pas la fin de ligne.

Exemple, je voudrais saisir :
1
2
x
y
Et obtenir :
a> 1
b> 2
c> x
d> y
Un code naïf pourrait donc être :
int a = scanner.nextInt();
int b = scanner.nextInt();
String c = scanner.nextLine();
String d = scanner.nextLine();
System.out.println("a> " + a);
System.out.println("b> " + b);
System.out.println("c> " + c);
System.out.println("d> " + d);

Or en réalité cela donne ceci (la touche Entrée après le 2 a été pris dans le c)
1
2
x
a> 1
b> 2
c>
d> x
Et en bidouillant on peut aussi faire ceci (le délimiteur entre 1 et 2 n'est alors plus le saut de ligne mais l'espace)
1 2
x
a> 1
b> 2
c>
d> x
Ou encore ceci (en enlevant le saut de ligne après le 2 pour avoir directement la ligne du x dans le c... mais avec un espace en trop)
1 2 x
y
a> 1
b> 2
c> x
d> y
Au final, aucune des trois saisies n'est correcte. La bonne solution étant de forcer la consommation de la fin de ligne après la lecture de chaque nextInt()

int a = scanner.nextInt(); scanner.nextLine();
int b = scanner.nextInt(); scanner.nextLine();
String c = scanner.nextLine();
String d = scanner.nextLine();
System.out.println("a> " + a);
System.out.println("b> " + b);
System.out.println("c> " + c);
System.out.println("d> " + d);

Remarque : ce piège vient juste du fait que l'on utilise System.in
Si on pense à un fichier texte il est normal de se dire que plusieurs nextInt() successifs vont lire plusieurs entiers sur la même ligne de texte.

Pour System.in le mieux est donc d'utiliser des petites méthodes utilitaires comme j'ai pu en montrer plus haut afin de ne pas se poser trop de questions à chaque utilisation de Scanner.
0