5

Does anyone see a problem with this? First input works fine, but after the first loop, it doesn't ask to enter a value again. How do I fix this?

    int value;
    while(true)
    {
        Scanner scan = new Scanner(System.in);
        System.out.println("Enter a value");
        try 
        {
            value = scan.nextInt();
            System.out.println("value provided is: " + value);
            scan.nextLine(); // consumes "\n" character in buffer
        }
        catch(InputMismatchException e) // outputs error message if value provided is not an integer
        {
            System.out.println("Incorrect input type. Try again.");
            continue; // restarts while loop to allow for re-entering of a valid input
        }
        scan.close();
    }
Alan
  • 153
  • 1
  • 4
  • 11

3 Answers3

5

Move scan.close(); to outside the while loop.

Also you don't have to construct a new Scanner on each iteration. Move the declaration to outside the loop as well.


When close the Scanner, this closes the System.in input stream.

So now when you try to instantiate it again, it doesn't find any opened stream and you'll get that exception.

Maroun
  • 94,125
  • 30
  • 188
  • 241
  • Are there cases where it's necessary to instantiate more than one scanner for a program? – Alan Dec 23 '13 at 08:57
  • What's wrong with my logic? I open and then close a scanner... at the next iteration this repeats. I don't see what's the problem with mine – Alan Dec 23 '13 at 09:04
  • Since [`close()`](http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#close()) closes the underlying stream, there will be nothing to read in the next iteration. See [this](http://stackoverflow.com/questions/5919143/is-it-safe-not-to-close-a-java-scanner-provided-i-close-the-underlying-readable) post. – Maroun Dec 23 '13 at 09:06
  • But doesn't it gets opened back again? This line gets executed again on the next iteration -> Scanner scan = new Scanner(System.in); – Alan Dec 23 '13 at 09:07
  • Why won't there be anything to read? My theory was that on the second iteration, it gets opened back and asks for value provided again. Why isn't this the case? – Alan Dec 23 '13 at 09:21
0

At the end of the while loop you have written scan.close(). This will close the scanner preventing any further scans. Removing that statement would ensure your while loop keeps asking you for the number(will be an infinite loop in your case)

Also, scan.nextInt() in effect ignores all new line and waits till you actually input a number and hit enter. So, scan.nextLine() can be omitted. You need that only in case where you use scan.nextLine() to fetch the value entered. In that case, the new line character is also read as an input, as a result of which you need an extra nextLine() call to consume it.

Adarsh
  • 3,613
  • 2
  • 21
  • 37
0

When you do scan.close(), it closes the underlying System.in stream. So in the next iteration it will not have anything to read.

For example:

import java.io.IOException;
import java.util.InputMismatchException;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        int value;
        while (true) {
            Scanner scan = new Scanner(System.in);
            System.out.println("Enter a value");
            try {
                value = scan.nextInt();
                System.out.println("value provided is: " + value);
                scan.nextLine(); // consumes "\n" character in buffer
            } catch (InputMismatchException e) // outputs error message if value
                                                // provided is not an integer
            {
                System.out.println("Incorrect input type. Try again.");
                continue; // restarts while loop to allow for re-entering of a
                            // valid input
            }
            scan.close();
            try {
                int x = System.in.read();
                System.out.println(x);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

OUTPUT:

Enter a value
10
value provided is: 10
Enter a value
java.io.IOException: Stream closed
    at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:162)
    at java.io.BufferedInputStream.fill(BufferedInputStream.java:206)
    at java.io.BufferedInputStream.read(BufferedInputStream.java:254)
    at Main.main(Main.java:24)
Exception in thread "main" java.util.NoSuchElementException
    at java.util.Scanner.throwFor(Scanner.java:907)
    at java.util.Scanner.next(Scanner.java:1530)
    at java.util.Scanner.nextInt(Scanner.java:2160)
    at java.util.Scanner.nextInt(Scanner.java:2119)
    at Main.main(Main.java:12)

Check this question for more:

Is it safe not to close a Java Scanner, provided I close the underlying readable?

Community
  • 1
  • 1
tuxdna
  • 8,257
  • 4
  • 43
  • 61