Alors je vois pas trop le problème il suffit simplement de faire :
Code:
1
2
3
4
5String line = lecteur.nextLine(); if (line.length() == 1){ // ton traitement }
Version imprimable
Alors je vois pas trop le problème il suffit simplement de faire :
Code:
1
2
3
4
5String line = lecteur.nextLine(); if (line.length() == 1){ // ton traitement }
peut-être que vous confondez caractères blancs et chaîne vide
Salut,
Voici la solution que j'ai trouvé pour contrôler les entrées au niveau de mon menu.
P.S: Il apparaitrais que l'affection"char c = 'a';" soit syntaxiquement correcte en Java.Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138 public void menu() { boolean continueLoop = true; int choixNombre = 0; String choixLettre = null; Livre instanceLivre; String chaineRecherche; // Chaîne envoyée aux fonctions métiers do { System.out.println("Menu:"); System.out.println("1) Créer un nouvelle entrée"); System.out.println("2) Rechercher un livre"); System.out.println("3) Afficher les livres"); System.out.println("4) Remplissage automatique du catalogue"); System.out.println("5) Sortir du menu"); if( lecteur == null ) { lecteur = new Scanner(System.in); lecteur.nextLine(); } do { try { System.out.print("Choix:"); choixNombre = lecteur.nextInt(); continueLoop = false; // On passe à cette instruction uniquement s'il n'y a pas d'exception } catch( InputMismatchException e ) { System.out.println( "[Erreur] Veuillez entrer un nombre décimal."); System.out.println("Debug:" + e ); lecteur.nextLine(); // On annule l'entrée } } while( continueLoop ); // Gestion du menu switch( choixNombre ) { case 1: System.out.println("Création d'un livre..."); instanceLivre = creerLivre(); if( instanceLivre == null ) System.out.println("Livre non créé !"); break; case 2: lecteur.nextLine(); System.out.print("Souhaitez vous effectuer une recherche par: \n" + "a) Titre \n" + "b) Code isbn \n"); continueLoop = true; do { System.out.print("Choix:"); choixLettre = lecteur.nextLine(); if( choixLettre.length() == 0 || choixLettre.length() > 1 ) { System.out.println("[Erreur] Veuillez entrer une et une seule lettre"); continueLoop = true; } else { if( !Character.isLetter( choixLettre.charAt(0) ) ) { System.out.println("[Erreur] Veuillez entrer une et une seule lettre"); continueLoop = true; } else continueLoop = false; } } while( continueLoop ); //if( choixLettre.length() < 0 || choixLettre.length() > 1 ) // System.out.println("[Erreur] Vous devez rentrer un et un seul caractère."); if( choixLettre.charAt(0) == 'A' ) { System.out.println("Veuillez entrer le titre recherché:"); chaineRecherche = lecteur.nextLine(); instanceLivre = rechercheTitre( chaineRecherche ); if( instanceLivre != null ) System.out.println( instanceLivre ); else System.out.println( "Livre non trouvé" ); } else if( choixLettre.charAt(0) == 'B' ) { System.out.println("Veuillez entrer le code isbn recherché:"); chaineRecherche = lecteur.nextLine(); instanceLivre = rechercheIsbn( chaineRecherche ); if( instanceLivre != null ) System.out.println( instanceLivre ); else System.out.println( "Livre non trouvé" ); } else System.out.println("Choix non valide. Veuillez relancer l'opération."); break; case 3: System.out.println("Affichage des livres..."); afficherTri(); break; case 4: System.out.println("Remplissage automatique du catalogue..."); remplissage(); break; case 5: System.out.println("Sortie du menu en cours..."); break; default: System.out.println("Choix non valide !"); } } while( choixNombre != 5 ); }
Bien sûr que c'est correct, tu penses que ça ne devrait pas l'être ? :koi:
J'ai parcouru vite fait ton code.
Quelques remarques :
Lisibilité du code :
- Utiliser la même variable continueLoop dans deux boucles différentes peut entraîner des confusions alors que deux variables différentes auraient très bien fait l'affaire. De plus, cette variable pourrait être remplacée par les instructions continue; et break;.
- Coder le sous-menu dans une fonction séparée permettrait de réduire le nombre de boucles imbriquées.
Tu proposes les choix a) ou b) mais tu testes la valeur du caractère sur A ou B, c'est perturbant :aie:
Je ne sais pas comment est initialisé le champ lecteur dans ta classe, donc peut-être que ce problème ne se pose en fait jamais, mais : si le champ lecteur est null quand on entre dans la fonction, alors on affiche le menu, puis le scanner attend que l'utilisateur tape une ligne + entrée (donc là l'utilisateur croit qu'il doit taper son choix... mais en fait non !), puis on affiche "Choix:" (et là l'utilisateur se demande ce qui s'est passé juste avant). C'est un peu gênant. Tu peux sans doute supprimer l'instruction "lecteur.nextLine();".Code:
1
2
3
4
5
6
7
8
9 System.out.println("Menu....."); if( lecteur == null ) { lecteur = new Scanner(System.in); lecteur.nextLine(); } // ... System.out.print("Choix:"); choixNombre = lecteur.nextInt();
En revanche, dans le cas où le champ lecteur était déjà initialisé : il est possible que le scanner contienne déjà des données, qui seront ensuite interprétées par scanner.nextInt() ! C'est dans ce cas ci qu'il pourrait être utile de vider le scanner avant de commencer l'affichage du menu (ça dépend évidemment du contexte dans lequel tu comptes utiliser la fonction menu).
Exemple d'utilisation de la fonction menu() qui pose problème :
A l'exécution je tape "abc def ghi[entrée]" => le scanner lit le premier mot "abc" puis on entre dans menu() et là l'appel de nextInt() sur le "def ghi[entrée]" provoque évidemment un message d'erreur.Code:
1
2
3 lecteur = new Scanner(System.in); lecteur.next(); menu();
Dans le même genre :
Si à la première question je réponds "1 1 1[entrée]", alors :Code:
1
2
3
4
5
6
7 do { System.out.println("Menu....."); // boucle sur nextInt() jusqu'à ce qu'on récupère un nombre // traitement en fonction du nombre récupéré } while( choixNombre != 5 );
- on récupère 1 avec nextInt()
- on effectue le traitement correspondant au choix 1
- on affiche le menu
- on récupère 1 avec nextInt()
- on effectue le traitement correspondant au choix 1
- on affiche le menu
- on récupère 1 avec nextInt()
- on effectue le traitement correspondant au choix 1
- on affiche le menu
Je ne suis pas sûre que tu aies prévu de laisser les utilisateurs effectuer plusieurs actions de suite... Apparemment tu vides la ligne en cas d'erreur sur nextInt (donc "a 1 a" ne provoquera qu'un seul message d'erreur et pas une erreur, un traitement, une erreur) et à l'entrée du traitement 2 (où l'on utilise le scanner). Peut-être vides-tu également la ligne dans toutes les fonctions que tu appelles et que je ne vois pas dans cet extrait, et donc avec le vrai "traitement correspondant au choix 1" ce problème ne se pose pas :mrgreen: mais il serait sans doute plus clair et plus propre de le faire systématiquement au moment où on récupère choixNombre.
Dans le sous-menu, si l'on entre un caractère non valide (ex:'o') qui est tout de même un caractère, comme on s'en rend compte après être sorti de la boucle qui permet la saisie on revient au premier menu. Là ce n'est pas bien grave, mais imagine que tu rajoutes des sous-menus en utilisant la même méthode, ça peut être énervant de devoir tout refaire à chaque erreur de frappe !
Je verrais plus une structure du genre:
Tant qu'on n'a pas réussi le traitement, on boucle et donc on redemande une entrée. Si on arrive au break final c'est qu'on a réussi.Code:
1
2
3
4
5
6
7
8 while (true) { // demande et récupération d'une entrée // traitement if (/*on se rend compte que l'entrée n'est pas valide*/) continue; // traitement break; }
Remarque valable également pour le premier menu, sauf que comme c'est le menu principal et qu'il est prévu pour boucler que l'entrée soit valide ou non on ne se rend compte de rien :mrgreen:
Astartee, merci d'avoir pris la peine d'analyser tout le code. Il s'agit là de bonnes remarques qui permettrons d'affiner mon style. Je posterais une réponse une fois que j'aurais le temps de réflêchir à cela.
Mais une constante qui s'appelle CHAINE_VIDE et qui est de type String, tu comptes y mettre quoi dedans à part "" ?
Perso, je vois autant d'utilité sur ce coup là que de déclarer un entier constant ZERO dont la valeur est 0.
Le symbole "", ça veut exactement dire chaine vide. 0, ça veut déjà dire : entier de valeur nul.
C'est pas comme s'il y avait un besoin de donner une sémantique particulière à un entier bizarre : Integer.MAX_VALUE par exemple.
Par contre, pour les autres cas, oui, tu as raisons, c'est souvent très utile ;)