J'utilise les Scanner
méthodes nextInt()
et nextLine()
pour lire les entrées.
Cela ressemble à ceci:
System.out.println("Enter numerical value");
int option;
option = input.nextInt(); // Read numerical value from input
System.out.println("Enter 1st string");
String string1 = input.nextLine(); // Read 1st string (this is skipped)
System.out.println("Enter 2nd string");
String string2 = input.nextLine(); // Read 2nd string (this appears right after reading numerical value)
Le problème est qu'après avoir entré la valeur numérique, le premier input.nextLine()
est ignoré et le second input.nextLine()
est exécuté, de sorte que ma sortie ressemble à ceci:
Enter numerical value
3 // This is my input
Enter 1st string // The program is supposed to stop here and wait for my input, but is skipped
Enter 2nd string // ...and this line is executed and waits for my input
J'ai testé mon application et il semble que le problème réside dans son utilisation input.nextInt()
. Si je le supprime, les deux string1 = input.nextLine()
et string2 = input.nextLine()
sont exécutés comme je le souhaite.
java
io
java.util.scanner
blekione
la source
la source
Réponses:
En effet, la
Scanner.nextInt
méthode ne lit pas le caractère de nouvelle ligne dans votre entrée créée en appuyant sur "Entrée", et donc l'appel àScanner.nextLine
revient après avoir lu cette nouvelle ligne .Vous rencontrerez le comportement similaire lorsque vous utilisez
Scanner.nextLine
aprèsScanner.next()
ou touteScanner.nextFoo
méthode (saufnextLine
elle-même).Solution de contournement:
Soit vous passez un
Scanner.nextLine
appel après chacun,Scanner.nextInt
soitScanner.nextFoo
vous consommez le reste de cette ligne, y compris la nouvelle ligneOu, encore mieux, lisez l'entrée
Scanner.nextLine
et convertissez-la au format approprié dont vous avez besoin. Par exemple, vous pouvez convertir un entier en utilisant laInteger.parseInt(String)
méthode.la source
try-catch
, carInteger.parseInt
jetteNumberFormatException
lorsqu'un argument non valide lui est passé. Vous découvrirez l'exception plus tard. Pour EG: -Integer.parseInt("abc")
. Vous ne voulez pas que "abc" soit converti en int?Scanner#hasNextFoo
chèque à l'avance au lieu d'un try-catch, mais cela fonctionne aussi.Le problème vient de la méthode input.nextInt () - elle ne lit que la valeur int. Ainsi, lorsque vous continuez à lire avec input.nextLine (), vous recevez la touche Entrée "\ n". Donc, pour ignorer cela, vous devez ajouter le input.nextLine () . J'espère que cela devrait être clair maintenant.
Essayez-le comme ça:
la source
nextLine
, mais j'ai toujours besoin d'une explication de ce comportementC'est parce que lorsque vous entrez un nombre puis appuyez sur Enter,
input.nextInt()
ne consomme que le nombre, pas la "fin de ligne". Lorsqu'ilinput.nextLine()
s'exécute, il consomme la "fin de ligne" toujours dans le tampon de la première entrée.Au lieu de cela, utilisez
input.nextLine()
immédiatement aprèsinput.nextInt()
la source
Il semble y avoir beaucoup de questions sur ce problème
java.util.Scanner
. Je pense qu'une solution plus lisible / idiomatique serait d'appelerscanner.skip("[\r\n]+")
pour supprimer tous les caractères de nouvelle ligne après l'appelnextInt()
.EDIT: comme @PatrickParker l'a noté ci-dessous, cela provoquera une boucle infinie si l'utilisateur entre des espaces après le nombre. Voir leur réponse pour un meilleur modèle à utiliser avec skip: https://stackoverflow.com/a/42471816/143585
la source
Il le fait parce
input.nextInt();
qu'il ne capture pas la nouvelle ligne. vous pourriez faire comme les autres proposés en ajoutant uninput.nextLine();
dessous.Alternativement, vous pouvez le faire en style C # et analyser une nextLine en un entier comme ceci:
Faire cela fonctionne aussi bien et cela vous permet d'économiser une ligne de code.
la source
TL; DR À utiliser
scanner.skip("\\R")
avant chaquescanner.newLine()
appel, qui est exécuté après:scanner.next()
scanner.next*TYPE*()
méthode.Ce que vous devez savoir:
le texte qui représente quelques lignes contient également des caractères non imprimables entre les lignes (nous les appelons séparateurs de lignes) comme
"\r"
)"\n"
)lorsque vous lisez des données à partir de la console, cela permet à l'utilisateur de taper sa réponse et lorsqu'il a terminé, il doit en quelque sorte confirmer ce fait. Pour ce faire, l'utilisateur doit appuyer sur la touche "Entrée" / "Retour" du clavier.
Ce qui est important, c'est que cette clé, en plus de garantir le placement des données utilisateur sur l'entrée standard (représentée par
System.in
laquelle est lu parScanner
), envoie également des séparateurs de ligne dépendants du système d'exploitation (comme pour Windows\r\n
).Ainsi, lorsque vous demandez à l'utilisateur une valeur telle que
age
, et que l'utilisateur tape 42 et appuie sur Entrée, l'entrée standard contient"42\r\n"
.Problème
Scanner#nextInt
(et d'autres méthodes) ne permet pas au scanner de consommer ces séparateurs de ligne. Il les lira (comment le scanner pourrait-il savoir qu'il n'y a pas plus de chiffres de l'utilisateur qui représentent une valeur que face aux espaces blancs?) Qui les supprimera de l'entrée standard, mais il mettra également en cache ces séparateurs de ligne en interne . Ce dont nous devons nous souvenir, c'est que toutes les méthodes du scanner sont toujours en train de numériser à partir du texte mis en cache.Scanner#nextType
System.in
age
Maintenant, il
Scanner#nextLine()
suffit de collecter et de retourner tous les caractères jusqu'à ce qu'il trouve des séparateurs de ligne (ou la fin du flux). Mais comme les séparateurs de lignes après avoir lu le numéro à partir de la console se trouvent immédiatement dans le cache de Scanner, il renvoie une chaîne vide, ce qui signifie que Scanner n'a pas pu trouver de caractère avant ces séparateurs de lignes (ou fin de flux).BTW consomme
nextLine
également ces séparateurs de ligne.Solution
Ainsi, lorsque vous souhaitez demander un numéro, puis une ligne entière, tout en évitant cette chaîne vide à la suite de
nextLine
, soitnextInt
cache des scanners parnextLine
,skip("\\R")
ouskip("\r\n|\r|\n")
de laisser le scanner ignorer la partie correspondant au séparateur de ligne (plus d'informations sur\R
: https://stackoverflow.com/a/31060125 )nextInt
(ninext
, ni aucunenextTYPE
méthode) du tout. Au lieu de cela, lisez l'intégralité des données ligne par ligne en utilisantnextLine
et en analysant les numéros de chaque ligne (en supposant qu'une ligne ne contient qu'un seul numéro) au type approprié, commeint
viaInteger.parseInt
.BTW : les méthodes peuvent ignorer les délimiteurs (par défaut, tous les espaces comme les tabulations, les séparateurs de lignes), y compris ceux mis en cache par le scanner, jusqu'à ce qu'ils trouvent la prochaine valeur non délimitante (jeton). Merci à cela pour l'entrée comme le code
Scanner#nextType
"42\r\n\r\n321\r\n\r\n\r\nfoobar"
sera en mesure d'assigner correctement
num1=42
num2=321
name=foobar
.la source
Au lieu d'
input.nextLine()
utiliserinput.next()
, cela devrait résoudre le problème.Code modifié:
la source
Si vous souhaitez lire les chaînes et les entiers, une solution consiste à utiliser deux scanners:
la source
scanner.nextLine()
devrait fonctionner.Si vous souhaitez analyser rapidement les entrées sans vous perdre dans la méthode nextLine () de la classe Scanner, utilisez pour cela un scanner d'entrée personnalisé.
Code:
Avantages:
Méthodes:
Utilisation:
ScanReader sc = new ScanReader(System.in);
3. Importez les classes nécessaires:import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream;
4. Lancez IOException à partir de votre méthode principale pour gérer l'exception 5. Utilisez les méthodes fournies. 6. ProfitezExemple :
la source
Afin d'éviter le problème, utilisez
nextLine();
immédiatement aprèsnextInt();
car cela aide à vider le tampon. Lorsque vous appuyez surENTER
lenextInt();
ne capture pas la nouvelle ligne et, par conséquent, ignore leScanner
code plus tard.la source
sc.nextLine()
est meilleure par rapport à l'analyse de l'entrée. Parce que sur le plan des performances, ce sera bon.la source
Je suppose que je suis assez tard pour la fête ..
Comme indiqué précédemment, appeler
input.nextLine()
après avoir obtenu votre valeur int résoudra votre problème. La raison pour laquelle votre code n'a pas fonctionné était qu'il n'y avait rien d'autre à stocker à partir de votre entrée (où vous avez entré l'int) dansstring1
. Je vais juste jeter un peu plus de lumière sur l'ensemble du sujet.Considérez nextLine () comme l' intrus parmi les méthodes nextFoo () de la classe Scanner. Prenons un exemple rapide. Disons que nous avons deux lignes de code comme celles ci-dessous:
Si nous entrons la valeur ci-dessous (comme une seule ligne d'entrée)
La valeur de notre
firstNumber
etsecondNumber
variable devient respectivement 54 et 234. La raison pour laquelle cela fonctionne de cette façon est qu'un nouveau saut de ligne ( c'est-à-dire \ n ) N'EST PAS généré automatiquement lorsque la méthode nextInt () prend les valeurs. Il prend simplement le "prochain int" et passe à autre chose. C'est la même chose pour le reste des méthodes nextFoo () sauf nextLine ().nextLine () génère un nouveau saut de ligne immédiatement après avoir pris une valeur; c'est ce que @RohitJain veut dire en disant que le nouveau fil de ligne est "consommé".
Enfin, la méthode next () prend simplement la chaîne la plus proche sans générer de nouvelle ligne; cela en fait la méthode préférentielle pour prendre des chaînes séparées sur la même ligne.
J'espère que cela aide .. Joyeux codage!
la source
Utilisez 2 objets scanner au lieu d'un
la source
la source
si j'attends une entrée non vide
utilisé dans l'exemple ci-dessus:
la source
Dans l'un de mes cas d'utilisation, j'ai eu le scénario de lecture d'une valeur de chaîne précédée de quelques valeurs entières . J'ai dû utiliser une " boucle for / while " pour lire les valeurs. Et aucune des suggestions ci-dessus n'a fonctionné dans ce cas.
Utiliser
input.next()
au lieu deinput.nextLine()
résoudre le problème. J'espère que cela pourrait être utile pour ceux qui font face à un scénario similaire.la source
Utilisez ce code, il résoudra votre problème.
la source
Comme les
nextXXX()
méthodes ne lisent pasnewline
, saufnextLine()
. Nous pouvons ignorernewline
après avoir lu n'importe quellenon-string
valeur (int
dans ce cas) en utilisantscanner.skip()
comme ci-dessous:la source
Pourquoi ne pas utiliser un nouveau scanner pour chaque lecture? Comme ci-dessous. Avec cette approche, vous ne confronterez pas votre problème.
la source
Scanner
pour éviter les fuites de mémoire. Perdre du temps?nextInt()
ne consommera pas la nouvelle ligne, qu'elle soit dans une "nouvelle"Scanner
ou une déjà utilisée.