How can I prevent java.util.Scanner from throwing NoSuchElementException when reading from System.in?

52 Views Asked by At

I'm attempting to ask the user for a double value, using Scanner.nextDouble(); but I'm getting a NoSuchElementException before I have a chance to type anything. From what I can see in the documentation, this means that Scanner is at the end of the input. However, I don't understand how that can happen when the Scanner is reading from System.in, not a file.

Is it possible that having other Scanners open is causing this? I don't think that should be the case, as another method is successfully run before this code that opens and closes another Scanner. But I don't really know enough about the ins and outs of Scanner (or much else!) to know if that is the issue.

Here's where I'm at currently, after a lot of failed attempts to re-write this code to get it working:

public static double collectDepositAmount(int accountNum){
    System.out.print("Enter how much you would like to deposit in Account #" + accountNum + ": $");
    Scanner userInput = new Scanner(System.in);
    double finalDeposit;
    try{
        double inputDeposit;
        inputDeposit = userInput.nextDouble();

There's more after that, but the exception always gets thrown at userInput.nextDouble();. The catch block is only looking for InputMismatchException, and I close userInput right before I return a valid double.

1

There are 1 best solutions below

2
rzwitserloot On

Either you closed System.in, or, the next token isn't parsable as a double. It could be either issue; they'd both result in a NoSuchElementException.

You closed System.in

Perhaps you closed it before ever calling this code (which doesn't close System.in, fortunately), which is easier than you might think. This will do it:

try (Scanner s = new Scanner(System.in)) {
 // stuff here
}

After that try block is done, System.in is now closed (solution: Don't close System.in; don't close anything that you wrapped around System.in either).

There's no double there

It could also simply be that the next token available is not a double, then you also get this exact same behaviour. To 'detect' that, call .next() instead, see if you do get something (and, what that is, for example by printing it). Could be that you're entering 5,20 and the system was expecting you to use dots for decimal separators (e.g. 5.20) instead, thus concluding the next token isn't a double, and throwing that same exception.