3

Have been struggling with this for a day, reading the discussion forum back and forth, no result. Anyone can tell me why the second call of the function aMenu() returns a zero and does not wait for new user input instead? I tried various things, like hasNextInt(), nextLine(), nothing worked. Shouldn't hasNextInt() block until the user writes something? How can I solve this? Thanks.

package FirstJavaPackage;
import java.util.Scanner;

public class testScanner
{
    public static void main(String[] args)
    {
        int choice = aMenu();
        System.out.println("You typed: "+choice);
        choice = aMenu();
        System.out.println("You typed: "+choice);
    }

    public static int aMenu()
    {
        int result = 0;
        System.out.println("In aMenu... enter an int: ");
        Scanner keyboard = new Scanner(System.in);
        if (keyboard.hasNextInt())
            result = keyboard.nextInt();
        keyboard.close();
        return result;
    }
}

The output is:

In aMenu... enter an int: 2 You typed: 2 In aMenu... enter an int: You typed: 0

x x
  • 35
  • 1
  • 4

3 Answers3

1

You need to re-use the same Scanner object across the calls to aMenu():

public static void main(String[] args)
{
    Scanner keyboard = new Scanner(System.in);
    int choice = aMenu(keyboard);
    System.out.println("You typed: "+choice);
    choice = aMenu(keyboard);
    System.out.println("You typed: "+choice);
}

public static int aMenu(Scanner keyboard)
{
    int result = 0;
    System.out.println("In aMenu... enter an int: ");
    result = keyboard.nextInt();
    return result;
}

For further discussion, see How to use multiple Scanner objects on System.in?

Community
  • 1
  • 1
NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • Thanks all, now it works fine, but I still don't get the logic completely. Ok, I was closing the input stream by the end of the aMenu() function, BUT wasn't I opening it again at the next call, with the line Scanner keyboard = new Scanner(System.in) ? That's how I ment it to happen, and I had already read the links you recommended, but I guess I'm still missing something. Why doesn't it work like that, closing and re-opening the stream later? Thanks again, you are making a great community here! – x x Mar 07 '13 at 09:40
  • 1
    @xx: For one thing, when you call `keyboard.close()`, that will also close `System.in`. From that point on, you won't be able to read anything from `System.in`, irrespective of whether you attempt to create any further scanners. – NPE Mar 07 '13 at 09:42
  • Thanks, now I get it. So, once a stream is closed, it remains closed for the rest of the program and you cannot scan something that does not exist.. – x x Mar 07 '13 at 10:02
0

After the first call, you actually close the System.in input stream.

From the Scanner.close() documentation:

When a Scanner is closed, it will close its input source if the source 
implements the Closeable interface.

Try not to close your scanner at the end of aMenu: initialize the scanner outside the aMenu method and make the method use it.

Jean Logeart
  • 52,687
  • 11
  • 83
  • 118
0

Since scanner.close will close the entire input source, you should pass scanner to your aMenu method and do something like this:

import java.util.Scanner;

public class TestScanner
{
   public static void main(String[] args)
   {
      Scanner keyboard = new Scanner(System.in);
      int choice = 0;

      do
      {
         choice = aMenu(keyboard);
         System.out.println("You typed: " + choice);
      } while (choice > 0);

      keyboard.close();
    }

    public static int aMenu(Scanner keyboard)
    {
        int result = 0;
        System.out.println("In aMenu... enter an int: ");

        if (keyboard.hasNextInt())
           result = keyboard.nextInt();

        return result;
    }
}
Jugal Shah
  • 3,621
  • 1
  • 24
  • 35