J'utilise les méthodes Scanner
, 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, la première input.nextLine()
est ignorée et la seconde input.nextLine()
est exécutée, 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 l'utilisation de input.nextInt()
. Si je le supprime, les fonctions string1 = input.nextLine()
et string2 = input.nextLine()
sont exécutées comme je le souhaite.
En effet, la méthode Scanner.nextInt
ne lit pas le caractère newline créé en appuyant sur "Entrée". L’appel à Scanner.nextLine
est donc restitué après la lecture de ce newline.
Vous rencontrez le même comportement lorsque vous utilisez Scanner.nextLine
après Scanner.next()
ou n’importe quelle méthode Scanner.nextFoo
(sauf nextLine
elle-même).
Solution de contournement:
Mettez un appel Scanner.nextLine
après chaque Scanner.nextInt
ou Scanner.nextFoo
pour consommer le reste de cette ligne, y compris nouvelle ligne
int option = input.nextInt();
input.nextLine(); // Consume newline left-over
String str1 = input.nextLine();
Ou, mieux encore, lisez l'entrée Scanner.nextLine
et convertissez-la au format adéquat dont vous avez besoin. Par exemple, vous pouvez convertir un entier en utilisant Integer.parseInt(String)
method.
int option = 0;
try {
option = Integer.parseInt(input.nextLine());
} catch (NumberFormatException e) {
e.printStackTrace();
}
String str1 = input.nextLine();
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 "\ n". Donc, pour ignorer cela, vous devez ajouter le input.nextLine () . J'espère que cela devrait être clair maintenant.
Essayez comme ça:
System.out.print("Insert a number: ");
int number = input.nextInt();
input.nextLine(); // This line you have to add (It consumes the \n character)
System.out.print("Text1: ");
String text1 = input.nextLine();
System.out.print("Text2: ");
String text2 = input.nextLine();
C'est parce que lorsque vous entrez un numéro, appuyez sur Enter, input.nextInt()
ne consomme que le nombre, pas la "fin de ligne". Lorsque input.nextLine()
est exécuté, il utilise la "fin de ligne" toujours dans le tampon depuis la première entrée.
Utilisez plutôt input.nextLine()
immédiatement après input.nextInt()
Il semble y avoir beaucoup de questions sur ce problème avec Java.util.Scanner
. Je pense qu'une solution plus lisible/idiomatique serait d'appeler scanner.skip("[\r\n]+")
pour supprimer tous les caractères de nouvelle ligne après avoir appelé nextInt()
.
EDIT: comme @PatrickParker indiqué ci-dessous, cela provoquera une boucle infinie si l'utilisateur entre tout espace après le nombre. Voir leur réponse pour un meilleur modèle à utiliser avec skip: https://stackoverflow.com/a/42471816/143585
C'est parce que input.nextInt();
ne capture pas la nouvelle ligne. vous pouvez faire comme les autres proposés en ajoutant une input.nextLine();
dessous.
Vous pouvez aussi le faire en style C # et analyser une nextLine en un entier comme ceci:
int number = Integer.parseInt(input.nextLine());
Cela fonctionne aussi bien et vous économise une ligne de code.
Ce que vous devez savoir:
le texte qui représente peu de 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, l’utilisateur peut taper sa réponse et quand il a terminé, il doit confirmer en quelque sorte _. Pour ce faire, l'utilisateur doit appuyer sur la touche "Entrée"/"Entrée" du clavier.
Ce qui est important, c’est que cette clé, qui permet de placer les données utilisateur dans entrée standard (représentée par System.in
qui est lu par Scanner
), 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 saisit 42 et que vous appuyez sur Entrée, l'entrée standard contiendra "42\r\n"
.
Scanner#nextInt
(et les autres méthodes Scanner#nextType
) n'autorisent pas Scanner à consommer ces séparateurs de ligne. Il les lira à partir de System.in
(sinon, Scanner saurait qu’il n’ya plus de chiffres de l’utilisateur représentant la valeur age
plutôt qu’un caractère blanc?), Ce qui les enlèvera de l’entrée standard, mais il y aura aussi cache ces séparateurs de lignes en interne. Ce dont nous devons nous rappeler, c’est que toutes les méthodes Scanner analysent toujours à partir du texte mis en cache.
Maintenant, Scanner#nextLine()
recueille et renvoie simplement tous les caractères jusqu'à ce qu'il trouve des séparateurs de ligne} _ (ou fin du flux). Mais comme les séparateurs de lignes après avoir lu le numéro sur la console se trouvent immédiatement dans le cache de Scanner, il renvoie String vide, ce qui signifie que Scanner n'a pu trouver aucun caractère avant ces séparateurs de lignes (ou fin de flux).
BTW nextLine
également consomme ces séparateurs de ligne.
Ainsi, lorsque vous souhaitez demander un nombre puis une ligne entière tout en évitant cette chaîne vide à la suite de nextLine
,
nextInt
du cache des scanneurs par nextLine
,skip("\\R")
pour laisser Scanner ignorer la pièce correspondant à \R
qui représente un séparateur de ligne (plus d'informations sur \R
: https://stackoverflow.com/a/31060125 )nextInt
(ni next
, ni aucune méthode nextTYPE
). Lisez plutôt des lignes complètes de données ligne par ligne à l'aide de nextLine
et analysez les numéros de chaque ligne (en supposant qu'une ligne ne contient qu'un seul nombre) vers le type approprié, tel que int
via Integer.parseInt
.BTW: Scanner#nextType
les méthodes peuvent ignorer les délimiteurs (par défaut, tous les espaces, comme les tabulations et les séparateurs de ligne), y compris ceux mis en cache par l'analyseur, jusqu'à ce qu'ils trouvent la prochaine valeur (non-délimiteur). Merci à cela pour l'entrée comme le code "42\r\n\r\n321\r\n\r\n\r\nfoobar"
int num1 = sc.nextInt();
int num2 = sc.nextInt();
String name = sc.next();
pourra assigner correctement num1=42
num2=321
name=foobar
.
Au lieu de input.nextLine()
, utilisez input.next()
, cela devrait résoudre le problème.
Code modifié:
public static Scanner input = new Scanner(System.in);
public static void main(String[] args)
{
System.out.print("Insert a number: ");
int number = input.nextInt();
System.out.print("Text1: ");
String text1 = input.next();
System.out.print("Text2: ");
String text2 = input.next();
}
Afin d'éviter le problème, utilisez nextLine();
immédiatement après nextInt();
, car cela aide à vider le tampon. Lorsque vous appuyez sur ENTER
, la nextInt();
ne capture pas la nouvelle ligne et par conséquent, ignore le code Scanner
ultérieurement.
Scanner scanner = new Scanner(System.in);
int option = scanner.nextInt();
scanner.nextLine(); //clearing the buffer
Si vous souhaitez numériser une entrée rapidement sans vous embrouiller dans la méthode nextLine () de la classe Scanner, utilisez Scanneur d'entrée personnalisé.
class ScanReader {
/**
* @author Nikunj Khokhar
*/
private byte[] buf = new byte[4 * 1024];
private int index;
private BufferedInputStream in;
private int total;
public ScanReader(InputStream inputStream) {
in = new BufferedInputStream(inputStream);
}
private int scan() throws IOException {
if (index >= total) {
index = 0;
total = in.read(buf);
if (total <= 0) return -1;
}
return buf[index++];
}
public char scanChar(){
int c=scan();
while (isWhiteSpace(c))c=scan();
return (char)c;
}
public int scanInt() throws IOException {
int integer = 0;
int n = scan();
while (isWhiteSpace(n)) n = scan();
int neg = 1;
if (n == '-') {
neg = -1;
n = scan();
}
while (!isWhiteSpace(n)) {
if (n >= '0' && n <= '9') {
integer *= 10;
integer += n - '0';
n = scan();
}
}
return neg * integer;
}
public String scanString() throws IOException {
int c = scan();
while (isWhiteSpace(c)) c = scan();
StringBuilder res = new StringBuilder();
do {
res.appendCodePoint(c);
c = scan();
} while (!isWhiteSpace(c));
return res.toString();
}
private boolean isWhiteSpace(int n) {
if (n == ' ' || n == '\n' || n == '\r' || n == '\t' || n == -1) return true;
else return false;
}
public long scanLong() throws IOException {
long integer = 0;
int n = scan();
while (isWhiteSpace(n)) n = scan();
int neg = 1;
if (n == '-') {
neg = -1;
n = scan();
}
while (!isWhiteSpace(n)) {
if (n >= '0' && n <= '9') {
integer *= 10;
integer += n - '0';
n = scan();
}
}
return neg * integer;
}
public void scanLong(long[] A) throws IOException {
for (int i = 0; i < A.length; i++) A[i] = scanLong();
}
public void scanInt(int[] A) throws IOException {
for (int i = 0; i < A.length; i++) A[i] = scanInt();
}
public double scanDouble() throws IOException {
int c = scan();
while (isWhiteSpace(c)) c = scan();
int sgn = 1;
if (c == '-') {
sgn = -1;
c = scan();
}
double res = 0;
while (!isWhiteSpace(c) && c != '.') {
if (c == 'e' || c == 'E') {
return res * Math.pow(10, scanInt());
}
res *= 10;
res += c - '0';
c = scan();
}
if (c == '.') {
c = scan();
double m = 1;
while (!isWhiteSpace(c)) {
if (c == 'e' || c == 'E') {
return res * Math.pow(10, scanInt());
}
m /= 10;
res += (c - '0') * m;
c = scan();
}
}
return res * sgn;
}
}
ScanReader sc = new ScanReader(System.in);
3. Importer 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 Exception 5. Utiliser les méthodes fournies . 6. Prendre plaisir
import Java.io.BufferedInputStream;
import Java.io.IOException;
import Java.io.InputStream;
class Main{
public static void main(String... as) throws IOException{
ScanReader sc = new ScanReader(System.in);
int a=sc.scanInt();
System.out.println(a);
}
}
class ScanReader....
Si vous voulez lire les chaînes et les ints, une solution consiste à utiliser deux scanners:
Scanner stringScanner = new Scanner(System.in);
Scanner intScanner = new Scanner(System.in);
intScanner.nextInt();
String s = stringScanner.nextLine(); // unaffected by previous nextInt()
System.out.println(s);
intScanner.close();
stringScanner.close();
sc.nextLine()
est préférable à l'analyse syntaxique de l'entrée ..__Parce que les performances seront optimales.
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é est qu'il n'y avait rien d'autre à stocker de votre entrée (où vous avez entré l'int) dans string1
. Je vais juste apporter 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:
int firstNumber = input.nextInt();
int secondNumber = input.nextInt();
Si nous entrons la valeur ci-dessous (comme une seule ligne d’entrée)
54 234
Les valeurs de nos variables firstNumber
et secondNumber
deviennent respectivement 54 et 234. Cela s’explique par le fait qu’un nouveau saut de ligne (i.e\n)IS NOTest généré automatiquement lorsque la méthode nextInt () prend les valeurs. Il prend simplement le "next int" et continue. 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 la nouvelle ligne est "consommée".
Enfin, la méthode next () prend simplement la chaîne la plus proche, String without générant une nouvelle ligne; cela en fait la méthode préférentielle pour prendre des chaînes séparées au sein d'une même ligne.
J'espère que cela aide .. Joyeux codage!
Utilisez 2 objets scanner au lieu d'un
Scanner input = new Scanner(System.in);
System.out.println("Enter numerical value");
int option;
Scanner input2 = new Scanner(System.in);
option = input2.nextInt();
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int i = scan.nextInt();
scan.nextLine();
double d = scan.nextDouble();
scan.nextLine();
String s = scan.nextLine();
System.out.println("String: " + s);
System.out.println("Double: " + d);
System.out.println("Int: " + i);
}