简体   繁体   中英

What is java.util.NoSuchElementException and how do i fix it?

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 xa 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';
        }

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.

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();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM