Wednesday 1 February 2017

java - Trouble with order of reading next line with Scanner




I am doing some basic java program using 'Scanner'. I read Integer, Double and String.



I have some issues with using scanner for String with other scanners like int and double.



Declaration part:



    Scanner scan = new Scanner(System.in);

int i2;
double d2;

String s2;


Order#1:



    i2 = scan.nextInt();
d2 = scan.nextDouble();
s2 = scan.nextLine();



Result:
Compiler waits to get input for i2 and d2 but not waiting for input for s2. It execute line after s2 = scan.nextLine(); instantly. When i debug, s2 is empty.



Order#2:



    i2 = scan.nextInt();
s2 = scan.nextLine();
d2 = scan.nextDouble();



Result:
Compiler waits to get input for i2 and s2 this time. When i give input hello it throws an error.



1
hello
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:864)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextDouble(Scanner.java:2413)
at HelloWorld.main(HelloWorld.java:18)



Order#3:



    s2 = scan.nextLine();
i2 = scan.nextInt();
d2 = scan.nextDouble();


Result:

works fine !!



So why order is playing role here?


Answer



The difference in execution, with change in orders, is due to the fact that new-line is not consumed by nextInt(), nextDouble(), next() or nextFoo() methods.



Therefore, whenever you place a call to nextLine() after any of those methods, it consumes that newline, and virtually skips over that statement.



The fix is simple, don't use nextFoo() methods before nextLine(). Try :-




i2 = Integer.parseInt(scan.nextLine());
d2 = Double.parseDouble(scan.nextLine());
s2 = scan.nextLine();


Or else, you could consume the new-line by



i2 = scan.nextInt();
d2 = scan.nextDouble();
scan.nextLine(); //---> Add this before the nextLine() call

s2 = scan.nextLine();


Order#3 works fine, as nextLine() is the first statement, and therefore, there are no left-over characters to consume.



Related: Scanner is skipping nextLine() after using next(), nextInt() or other nextFoo() methods


No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...