0

Using a while loop to prompt the user to enter 3 ints to average them out, need to reprompt when the input isn't an int, so I decided to take a step back in the loop when the input isn't an int, but when I enter a non int, it's as if it consistently goes to the condition that it isn't a int, and continues to reprompt, without rechecking for a new input.

  Scanner scnr = new Scanner(System.in);

    String prompt = "Type an integer: ";
    int num = 0;
    int i = 0;
    while (i < 3) {
        System.out.print(prompt);
        if (scnr.hasNextInt()) {
            int input = scnr.nextInt();
            num += input;
        } else i -= 1;

        i += 1;
    }
    
     double average = num / 3.0;
    System.out.println("Average: " + average);

CalebN99
  • 99
  • 2
  • 10
  • 4
    `hasNextInt()` only checks whether the next token is an int. It does not advance, so the not-int is still there. When the scanner checks in the next iteraton it checks the same token. You will have to call `next()` or `nextLine()` to actually take the token. – MDK Oct 27 '20 at 21:55
  • 2
    It goes to the condition "that it isn't an int" because you call `scnr.nextInt()` only if you have already an int, and you never leave your while loop because when i is lower than 3 and that you don't have an int, you subtract 1 mode to i : -1, -2, -3... So you never leaving your loop. – Marc Le Bihan Oct 27 '20 at 21:57
  • 1
    Related: [How to handle infinite loop caused by invalid input (InputMismatchException) using Scanner](https://stackoverflow.com/q/3572160) – Pshemo Oct 27 '20 at 21:57

2 Answers2

1

hasNextInt() only returns true if an int is already there -- it doesn't actually get input. That's what your call to nextInt() is doing. But that's never being called because hasNextInt() is always false, as you've never actually taken user input, so i is being decremented in the else block and then incremented again forever.

An alternative approach would be to use a try/catch block with nextInt() to get the next input value, and step back if that catches an exception (meaning the input was not an int).

Garrett Nix
  • 80
  • 1
  • 1
  • 7
  • I tried the try/catch and it's still causing it to go infinity, I probably wrote it wrong though. – CalebN99 Oct 27 '20 at 22:13
  • You'll want to put the `nextInt()` call inside the try block, and put the `i--` in the catch block. That way if any exceptions (errors) occur when trying to read the int that the user inputs, it will simply jump to the catch block, decrement `i` and loop again. – Garrett Nix Oct 28 '20 at 00:12
0

As a previous user has mentioned the main problem is that the hasNextInt() only checks and doesn't advance your scanner forward.

Here is how I would do this code, I hope it solves the issue:

    int counter = 0;
    boolean flag = false;
    int sum = 0;

    while(!flag){

        System.out.println(prompt);

        if (scnr.hasNextInt()){
            int input = Integer.parseInt(scnr.nextLine());
            sum = sum + input;
            counter++;
        }else{
            scnr.nextLine();
            System.out.println("You didn't enter an Integer.");
        }
        
        if (counter == 3){
            flag = true;
        }

    }

    double avg = sum / 3;
    System.out.println("Average: " + avg);

There are probably better ways of doing it than mine but I hope it helps, good luck!

4444P
  • 1
  • 2