4

I was trying to program a game of battleship and i ran into this error at the point where the user was prompted to enter their guess coordinates:

Exception in thread "main" java.util.NoSuchElementException


    at java.util.Scanner.throwFor(Unknown Source)
        at java.util.Scanner.next(Unknown Source)
        at java.util.Scanner.nextInt(Unknown Source)
        at java.util.Scanner.nextInt(Unknown Source)
        at game.User.takeTurn(User.java:121)
        at game.Game.main(Game.java:61)

Here is the method User.takeTurn() where the error occured:

    static void takeTurn() {
           System.out.println("Yout turn!");
           System.out.println("Enter your x guess:");
           Scanner scanInput = new Scanner(System.in);
           int x;
           x = scanInput.nextInt();
           System.out.println("You entered "+ x + ", Now enter your y     coord:");
           int y;
           y = scanInput.nextInt();
           System.out.println("You entered + " + y);
           if(Board.aiBoard[x][y] == 2) {
               System.out.println("Hit! You got a hit at: " + x + "," + y);
               Board.enemyBoardDisplay[x][y] = 'h';
               Board.aiBoard[x][y] = 3;
           }
           else {
            System.out.println("Miss!");
            Board.enemyBoardDisplay[x][y] = 'x';
            Board.aiBoard[x][y] = 1;
          }

           scanInput.close();
      }

Im not really sure if it matters or not but i also use another scanner earlier in the class. If you need more code to help just let me know. Thanks!

edit 1: Ok, even after I do scanInput.hasNextInt() its not working. I also put in an else statement that gave x a value but now x always has the value that the else statement gives. It dosent even ask for an input it just defaults to that value. But i dont want it to go to a default i want the user to pick.

edit 2: This is where i call the code in my main stub

while (gameOn == true) {
            if (turn == 0) {
                User.takeTurn();
                Board.sunkCheck();
                if (gameOn == false)
                    break;
            }

            else if (turn == 1) {
                Computer.takeTurn();
                Board.sunkCheck();
                if (gameOn == false)
                    break;
            }

This is where i use a scanner earlier in the same class as im trying to use the scanner now:

System.out
                .println("\n Please enter the first x value for your ship  (Note, this will be the first point, from this point the \n"
                        + " ship can either go vertically downward or horizontally to the right so please choose the topmost point or leftmost \n"
                        + "point to do this. Also, the board is 10x10 but due to java array indexing the coordinates go x 0-9 y 0-9: ");
        try {
        Scanner coord = new Scanner(System.in);
        userX = coord.nextInt();
        System.out.println("You entered: " + userX);
        System.out.println("Now enter the y coordinate for this point: ");
        userY = coord.nextInt();
        System.out.println("You entered: " + userY);
        System.out
                .println("Please choose the direction of your ship. Enter v for verticle or h for horizontal(case sensitive): ");
        dir = (char) System.in.read();
        coord.close();
        }
        catch(InputMismatchException e) {
            System.out.println("Good job doof, since you tried to troll we did all the values for you!");
            userX = 3;
            userY = 3;
            dir = 'v';
        }
Ashwin Gupta
  • 2,159
  • 9
  • 30
  • 60
  • 1
    Have you looked at the [API documentation](http://docs.oracle.com/javase/8/docs/api/java/util/NoSuchElementException.html)? Quote: "Thrown by various accessor methods to indicate that the element being requested does not exist." – Jesper Jan 31 '15 at 06:58
  • 1
    And also the docs of [`Scanner.nextInt()`](http://docs.oracle.com/javase/8/docs/api/java/util/Scanner.html#nextInt--): "Throws: NoSuchElementException - if input is exhausted" – Jesper Jan 31 '15 at 07:00

2 Answers2

3

You might want to check for next element before getting it in Scanner with scanInput.hasNextInt().


Updated:

If you use the above Scanner coord = new Scanner(System.in); and then call the function with Scanner scanInput = new Scanner(System.in); without closing the coord Scanner, then you will be having issues.

Scanners will continue to consume the stream - this may (will) lead to unexpected side-effects.

You may want to close the first one before using another (here for more ref).


Update:

When you close coord.close() you are closing System.in and when you try to re-read from it, it will throw the exception.

Instead of re-opening the stream every time you need input you could create your Scanner once and just re-using it.

Community
  • 1
  • 1
nitishagar
  • 9,038
  • 3
  • 28
  • 40
1

NoSuchElementException occurs when you try to read input from scanner and when input does not exists.

So before taking the input, you should check if scanner has some input for you to consume like:

if (scanInput.hasNextInt()) {
    x = scanInput.nextInt();
}
SMA
  • 36,381
  • 8
  • 49
  • 73
  • That shall be `scanInput` not scanner – frunkad Jan 31 '15 at 07:04
  • Hmm, when i did that the ide made all code after that have an error since x might not have a value. So i made an else statement that gave x a value but now x always has the value that the else statement gives. What might be causing the scanner to not have input to consume? – Ashwin Gupta Jan 31 '15 at 07:05
  • that's right. So initialize x with default value as 0 as `int x=0;`. – SMA Jan 31 '15 at 07:06
  • You can set a value to x while declaring – frunkad Jan 31 '15 at 07:06
  • But thats not what i want to do... I want a user to pick the input of x and for some reason that isnt working. Can someone please tell me why? – Ashwin Gupta Jan 31 '15 at 07:08
  • @AshwinGupta do you give the inputs in the console and it still takes the `else` part – nitishagar Jan 31 '15 at 07:10
  • You may use `while(!scanInput.hasNextInt());x = scanInput.nextInt();` notice ; after while – frunkad Jan 31 '15 at 07:10
  • well thats the problem, its not even letting me give inputs to the console it goes straight to the else – Ashwin Gupta Jan 31 '15 at 07:10
  • @AshwinGupta Can you post the snippet where you call this code and are there any other `Scanner` used in that scope – nitishagar Jan 31 '15 at 07:11
  • @Ashwin Gupta. Did you tried that `while` . Try this also `int x = scanInput.nextInt();` [both declaration and assignment on same line] – frunkad Jan 31 '15 at 07:26
  • Ok, i did the 2nd thing you said before i even posted the question, ill try the while thing, thanks! – Ashwin Gupta Jan 31 '15 at 07:27
  • Ok just tired your while thing! That actually worked kind of. It finally prompted me to enter an input which it wasnt letting me do before (just defaulted to my else) but now the input stream wont close, like it never terminates the program it just keeps letting me input things. – Ashwin Gupta Jan 31 '15 at 07:29
  • Then use `BufferedReader` – frunkad Jan 31 '15 at 07:34