2
package sandbox2;

import java.util.Scanner;

public class Sandbox2
{
    public static void main(String[] args)
    {
        for (int i = 0; i < 5; i++)
        {
            String s = askForProperty("Enter value for " + i + ": ");
            System.out.println(i + " is: " + s);
        }

    }

    private static String askForProperty(String message)
    {
        Scanner keyboard = new Scanner(System.in);
        System.out.print(message);
        String s = keyboard.nextLine();
        keyboard.close();

        return s;
    }
}

When i run the above code, it returns the first response PERFECTLY. When it tries to ask for the second response, it returns:

java.util.NoSuchElementException: No line found

Why would it return this error? Each time the method askForProperty is called, the Scanner is a completely new instance! Does it have something to do with System.in as an input stream?

Drifter64
  • 1,103
  • 3
  • 11
  • 30
  • 1
    Why did you choose to create a new Scanner each iteration? I believe the problem is that when you call `keyboard.close` you are closing the `System.in`. If you just make one scanner and close it after all iterations are done you should be ok. – takendarkk Feb 11 '14 at 18:35
  • This seems reasonable. I believe the close() method does close anything else the resource depends on. I was attempting to reduce code, as i was asking for many user inputs and didn't want loads of println statements either. – Drifter64 Feb 11 '14 at 18:41

3 Answers3

0

Define your scanner as a class variable and then close it only after you are done with all iterations. In your current setup, when you call keyboard.close you are also closing System.in which makes it unusable later on.

package sandbox2;
import java.util.Scanner;

public class Sandbox2 {
    static Scanner keyboard = new Scanner(System.in); // One instance, available to all methods

    public static void main(String[] args)  {
        for (int i = 0; i < 5; i++) {
            String s = askForProperty("Enter value for " + i + ": ");
            System.out.println(i + " is: " + s);
        }
        keyboard.close(); //Only close after everything is done.
    }

    private static String askForProperty(String message) {
        System.out.print(message);
        String s = keyboard.nextLine();
        return s;
    }
}
takendarkk
  • 3,347
  • 8
  • 25
  • 37
  • this is actually something along the lines of what i was thinking, except that i wasn't thinking about keeping it open the whole time. – Drifter64 Feb 11 '14 at 18:43
  • 1
    If it doesn't work (I tested it a few times, it should work for you) let me know what problems you encounter. – takendarkk Feb 11 '14 at 18:45
0

Closing a Scanner causes the underlying InputStream to be closed also. As there is only one System.in, any newly created Scanner objects will not be able to read from the same stream:

keyboard.close();

Close the Scanner in the last.

Kick
  • 4,823
  • 3
  • 22
  • 29
0

So,

The chief problem in your code is that you create and close Scanner immediately in every single iteration. That simply does not work. Imagine Scanner as a large connection to your IO that requires quite some assemblage. If you open / close it every single time - You might just find a case where the next command is fired before the connection is opened once again. It's very similar to what you might find in a DB connection as well. The way to prevent it is to have Scanner open BEFORE you start iterating, finish the loop and then close it.

Hence, remove the close() statement from the askForProperty() function and move it to your main. Pass the Scanner keyboard object to the function. Once all the iterations are over - Then close it.

import java.util.Scanner;

public class Sandbox2
{
    public static void main(String[] args)
    {
        Scanner keyboard = new Scanner(System.in); // Initialize the Scanner
        for (int i = 0; i < 5; i++)
        {
            String s = askForProperty("Enter value for " + i + ": ", keyboard); // Pass the Scanner
            System.out.println(i + " is: " + s);
        }
        keyboard.close(); // Close the Scanner now that the work is done.
    }

    private static String askForProperty(String message, Scanner keyboard)
    {
        System.out.println(message);
        String s = keyboard.nextLine();
        return s;
    }
}
gran_profaci
  • 8,087
  • 15
  • 66
  • 99