zZShort_CircuitZz zZShort_CircuitZz - 12 days ago 7
Java Question

Scanner nextLine() not waiting for input on loop

The following code takes an input of 1, 2, or 3 from

System.in
and acts accordingly, looping trials until the number "3 (or an invalid
String
)" is entered, and the program exits. I need to use
nextLine()
instead of
nextInt()
so that inputs like "123" or "123abc" all fall into the last "else" and cause the program to exit.
The program works fine the first time, but on the second iteration, the console outputs
Trial 2:
and then I get a
NoSuchElementException: No line found
. View the stack trace below.

public static void main(String[] args){
int trialNumber = 1;

Scanner s = new Scanner(System.in);
String input = null;
while (true) {
System.out.print("Trial " + trialNumber + ": ");
input = s.nextLine();
int type = determineInputType(input); //Parses input and returns 1 2 or 3

if (type == 1) {
// ...
}
else if (type == 2) {
// ...
}
else {
System.out.println("Exiting!");
break;
}
trialNumber++;
}
s.close();

}


Here is the stack trace:

Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Unknown Source)
at edu.iastate.cs228.hw4.InfixPostfix.main(InfixPostfix.java:39)


Thanks for the assistance!

EDIT: Below is the source for determineInputType(input)

private static int determineInputType(String input) {

switch (input) {
case "1":
return 1;
case "2":
return 2;
case "3":
return 3;
default:
System.out.println("Invalid option.");
return 0;
}
}

Answer

Likely you are creating a new Scanner in the determineInputType method, or somewhere in your // ....

When you close a Scanner, the InputStream that it uses gets closed too. So if you open a Scanner for System.in and then close it, every other opened Scanner won't be able to read from System.in anymore.

Example:

public static void main(String[]args) {
    // [...]
    Scanner s = new Scanner(System.in);
    String myString = s.nextLine();
    determineInputType(myString);
    // [...]
    s.close();
}

public static void determineInputType(String str) {
    // [...]
    Scanner s1 = new Scanner(System.in);
    // [...]

    /* This will affect the 's' Scanner from the 'main' method too
     * as it closes System.in, which is being used from 's' too
     */
    s1.close(); 

}