java.util.NoSuchElementException - Scanner reading user input
This has really puzzled me for a while but this is what I found in the end.
When you call, sc.close()
in first method, it not only closes your scanner but closes your System.in
input stream as well. You can verify it by printing its status at very top of the second method as :
System.out.println(System.in.available());
So, now when you re-instantiate, Scanner
in second method, it doesn't find any open System.in
stream and hence the exception.
I doubt if there is any way out to reopen System.in
because:
public void close() throws IOException --> Closes this input stream and releases any system resources associated with this stream. The general contract of close is that it closes the input stream. A closed stream cannot perform input operations and **cannot be reopened.**
The only good solution for your problem is to initiate the Scanner
in your main method, pass that as argument in your two methods, and close it again in your main method e.g.:
main
method related code block:
Scanner scanner = new Scanner(System.in);
// Ask users for quantities
PromptCustomerQty(customer, ProductList, scanner );
// Ask user for payment method
PromptCustomerPayment(customer, scanner );
//close the scanner
scanner.close();
Your Methods:
public static void PromptCustomerQty(Customer customer,
ArrayList<Product> ProductList, Scanner scanner) {
// no more scanner instantiation
...
// no more scanner close
}
public static void PromptCustomerPayment (Customer customer, Scanner sc) {
// no more scanner instantiation
...
// no more scanner close
}
Hope this gives you some insight about the failure and possible resolution.
NoSuchElementException in java.util.Scanner
NoSuchElementException
is thrown from Scanner.next()
if you are trying to read data when you have reached the end of the data stream.
Instead of:
sc.next();
...
use:
while(! sc.hasNext()) { }
sc.next();
...
Scanner.hasNext()
checks if there is any more data to read, and the while loop waits until there is more data to read before continuing.
NoSuchElementException with Java.Util.Scanner
NoSuchElementException
Thrown by the nextElement
method of an Enumeration to indicate that there are no more elements in the enumeration.
http://docs.oracle.com/javase/7/docs/api/java/util/NoSuchElementException.html
How about this :
if(input.hasNextInt() )
number1 = input.nextInt(); // if there is another number
else
number1 = 0; // nothing added in the input
Fixing java.util.NoSuchElementException for Scanner
Stop the madness of closing a Scanner
linked to System.in
! It will close the underlying stream (System.in
), causing any other attempt to read from that Stream
to throw an exception.
Yes you will get a warning, but it is safe to ignore that warning, or you can add
@SuppressWarnings("resource")
Scanner in = new Scanner(System.in);
To avoid it.
Remember, if you didn't open a resource, you shouldn't close it. Let the JVM close it when it terminates the program.
This also includes creating a Scanner(System.in)
inside a try with resources block:
try(Scanner in = new Scanner(System.in)){
//Code...
}
This will implicitly close the stream at the end of the block.
From the Java tutorials:
The try-with-resources statement ensures that each resource is closed at the end of the statement.
Also you have several Scanner
objects reading from System.in
, which is bad practice. I would pass them to your methods as a parameter:
public static double solvingForMass(Scanner in) {
System.out.println("Please enter a value for force.");
double f = in.nextDouble();
System.out.println("Please enter a value for acceleration.");
double a = in.nextDouble();
return f / a;
}
Also just a note that if you are ever doing the structure of:
if(someBool)
return true;
else
return false;
It can be simplified to just
return someBool
So your isValidChoice()
method can be simplified to:
public static boolean isValidChoiceChar(String c) {
return c.compareTo("Y") == 0 || c.compareTo("N") == 0;
}
Although note you can use the equals()
and equalsIgnoreCase()methods to compare
String`'s
Scanner next() throwing NoSuchElementException for some online compilers
This exception gets thrown because there are no more elements in the enumeration.
See the documentation:
Thrown by the nextElement method of an Enumeration to indicate that
there are no more elements in the enumeration.
Some online IDEs don't allow user input at all, in which case the exception will get thrown as soon as you try to read user input.
- It works on TutorialsPoint IDE because it allows user input.
- It doesn't works on codechef and compilejava IDEs because these IDEs does not support user input.
However there's secondary way to add user input on codechef. Just tick mark on Custom Input
checkbox and provide any input. It will then compile.
Another reason for this exception, i.e. there simply not being more user input, can be handled by, before calling s.next()
, just checking s.hasNext()
to see whether the scanner has another token.
Scanner s = new Scanner(System.in);
System.out.print("Enter name: ");
String name = null;
if(s.hasNext())
name = s.next();
System.out.println("Name is " + name);
how to fix : Exception in thread main java.util.NoSuchElementException: No line found
You're creating two Scanner
objects based on System.in
.
Each Scanner
will read from System.in
and consume some of its input. That means that the first one might have already read some things into its buffer when you created the second one.
The short answer is: never create multiple Scanner
objects based on the same parameter, simply continue using the existing scanner. For example this would fix your issue:
public static void main(String[] args) {
Scanner myScanner = new Scanner(System.in);
String userName = myScanner.nextLine();
System.out.print("Username is: " + userName);
String number = myScanner.nextLine();
// ... rest of your code ...
how to solve NoSuchElementException Error in Scanner of Java?
private static void gamePlay(boolean isPlaying) {
while (isPlaying) {
System.out.println("Choose a, d , s or w for movement:");
Scanner sc = new Scanner(System.in);
String choice = sc.next();
// code for movement of player according to a or s or d or w
switch (choice) {
case "a":
// Some code here
// move -x
break;
case "d":
// Some code here
// move +x
break;
case "w":
// Some code here
// move +y
break;
case "s":
// Some code here
// move -y
break;
case "q":
//quit
sc.close();
isPlaying = false;
break;
default:
break;
}
}
}
NoSuchElementException on Scanner, how do i get rid of it?
Don't invoke s.next()
twice, but assign the result of the first call to a variable:
while (s.hasNext()) {
String value = s.next();
if(value.contains(",")) {
String str = value.replaceAll("[^a-zA-Z0-9]", "");
List<String> brokenSentence = Arrays.asList(str.split(","));
writer.write(brokenSentence +"\n");
} else {
String edited = value.replaceAll("[^a-zA-Z0-9]", "");
writer.write(edited +"\n");
}
}
Continuously calling s.next()
will keep consuming values from the scanner. Those values are not necessarily there because you have only checked for the presence of one value using s.hasNext()
.
Related Topics
How to Choose the Id Generation Strategy When Using JPA and Hibernate
What Is the Regex to Extract All the Emojis from a String
Why Won't This Generic Java Code Compile
Why Is Java's Boolean Primitive Size Not Defined
How to Read PDF Files Using Java
How to Convert a Java 8 Stream to an Array
Spring Boot - Cannot Determine Embedded Database Driver Class for Database Type None
Maven Error: Could Not Find or Load Main Class Org.Codehaus.Plexus.Classworlds.Launcher.Launcher
How to Match String Within Parentheses (Nested) in Java
Setting Default Values for Columns in JPA
Does a Tcp Socket Connection Have a "Keep Alive"
Sorting Java Objects Using Multiple Keys
How to Represent Double Values as Circles in a 2D Matrix in Java
How to Force Selenium Webdriver to Click on Element Which Is Not Currently Visible
Purpose of Default or Defender Methods in Java 8
Maven - Always Download Sources and Javadocs