0

The questions are in the comments of the code, sorry for that, I thought it's neater, as the flow is important, I guess...

import java.util.Scanner;

    public class ReadingUserInput {
        public static void main(String[] args) {

            Scanner scanner = new Scanner(System.in);
            System.out.println("Please, enter 10 numbers, for example, from 1 to 100!");

            int number = 0;
            int total = 0;
            int counter = 0;


            while (counter < 10) {
                System.out.println("Enter number #" + (counter + 1));

                boolean hasNextInt = scanner.hasNextInt(); // here we open the prompt for user to enter the value/s*
                                                           // internally, we are ready to check if the input is going to be int
                                                           // user types the value/s and clicks enter
                                                           // let's presume, he/she typed '3'
                                                           // internally, user's input is like that (if Windows**) - '3\n'
                                                           // because when user presses Enter - \n is added to what he/she typed

                if (hasNextInt) {                           // the app checks, ant it's int, that is, it's OK (true)

                    number = scanner.nextInt();            //here the application grabs user's input
                                                           //but, internally, it grabs only '3', because 'nextInt()' grabs only ints
                                                            // and doesn't "care" about the new feed/line - \n - character
                                                           // so, '\n' is left in Scanner's buffer!


                    counter++;

                    total += number;

                } else {
                    System.out.println("Invalid Input! Try again!");

                }
                //scanner.nextLine();                     // let's presume, this commented line, on the left of this line of comment, is absent in our code
                                                          // the flow of our code goes to boolean hasNextInt = scanner.hasNextInt();
                                                          // and again internally, we are ready to check if the input is going to be int
                                                          // and again the user is prompted (by a blinking cursor) to type his/her input
                                                          // and at this moment user types either a numeric again or a non-numeric character (a letter/letters)
                                                          // let's presume he/she is typing '4'
                                                          // and again, internally, user's input is actually like that (if Windows**) - '4\n'
                                                          // but scanner.hasNextInt() says 'OK', for the int is there! and it doesn't care about '\n'
                                                          //
                                                          // Now, let's presume that user (this time or next time) types 'a'
                                                          // Do we actually have 'a\n' ???
                                                          // and this time scanner.hasNextInt() says 'Alarm' - 'false'
                                                          // thus the input doesn't go to number = scanner.nextInt();
                                                          // So, does it mean that 'a\n' (or 'a') remains in Scanner's buffer???
                                                          // and it (scanner.hasNextInt()) kicks us to 'else'
                                                          // and we have an endless loop:
                                                             //Invalid Input! Try again!
                                                             //Enter number #...
                                                             //Invalid Input! Try again!
                                                             //Enter number #...
                                                             //Invalid Input! Try again!
                                                             //Enter number #...
                                                             //Invalid Input! Try again!
                                                             //Enter number #...
                                                             //Invalid Input! Try again!
                                                             //Enter number #...
                                                             //Invalid Input! Try again!
                                                             //Enter number #...
                                                             //Invalid Input! Try again!
                                                             //Enter number #...
                                                           //Why?
                                                            // Is there still 'a' (or 'a\n') and scanner.hasNextInt() throws the flow to 'else' endlessly,
                                                            // because "The scanner does not advance past any input"* ???
                                                            //
                                                            // or: there's only '\n', and again its not int, and we result in endless loop ???

                                                            // And finally, is that a different case? https://www.youtube.com/watch?v=_xqzmDyLWvs
                                                            // And PS: Is there anything wrong in my description in the comments?         
// So what do we 'consume' by scanner.nextLine(); ???

                }
                scanner.close();
                System.out.println("Thank you, your total is " + total);
    }
}

// *This is from Oracle :(https://docs.oracle.com/javase/6/docs/api/java/util/Scanner.html#hasNextInt%28%29)

"hasNextInt

public boolean hasNextInt()

Returns true if the next token in this scanner's input can be interpreted as an int value in the default radix using the nextInt() method. The scanner does not advance past any input."

// **https://knowledge.ni.com/KnowledgeArticleDetails?id=kA00Z0000019KZDSA2

Mr. Brickowski
  • 818
  • 7
  • 16
  • Eugene, you are correct, "The scanner does not advance past any input" means that `a\n` remains in the buffer, so the loop will loop forever. --- *"what do we 'consume' by scanner.nextLine()"* The (rest of) the line of input, up to and including the `\n`. – Andreas May 12 '20 at 03:21
  • Thank you Andreas, this is what I wanted to hear! – Eugene Prott May 13 '20 at 18:22

2 Answers2

0

Create another scanner object instead and forget about what is left in the internal buffer.

public class ReadingUserInput {
    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);
        System.out.println("Please, enter 10 numbers, for example, from 1 to 100!");

        int number = 0;
        int total = 0;
        int counter = 0;

        while (counter < 10) {
            System.out.println("Enter number #" + (counter + 1));

            boolean hasNextInt = scanner.hasNextInt();

            if (hasNextInt) {
                number = scanner.nextInt();

                counter++;

                total += number;

            } else {
                System.out.println("Invalid Input! Try again!");
                scanner = new Scanner(System.in);
            }

        }
        scanner.close();
        System.out.println("Thank you, your total is " + total);
    }
}
Mr. Brickowski
  • 818
  • 7
  • 16
  • Never suggest creating another `Scanner` object for `System.in`. You must use only one `Scanner` object for `System.in` throughout the program. Also, never close `Scanner` object for `System.in` because it will also close `System.in` and there is no way to open `System.in` again. – Arvind Kumar Avinash May 12 '20 at 08:50
0

Use Scanner::nextLine instead of Scanner::nextInt

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("Please, enter 10 numbers, for example, from 1 to 100!");
        int number = 0;
        int total = 0;
        int counter = 0;
        boolean valid;
        while (counter < 10) {
            do {
                valid = true;// Start with valid as true
                System.out.print("Enter number #" + (counter + 1) + ": ");
                try {
                    // Parse the input to int
                    number = Integer.parseInt(scanner.nextLine());
                    counter++;
                    total += number;
                } catch (NumberFormatException e) {// Handle exception for non-integer input
                    System.out.println("Invalid Input! Try again!");
                    valid = false;// Set valid to false
                }
            } while (!valid);// Loop back as long as valid is false
        }
        System.out.println("Thank you, your total is " + total);
    }
}

A sample run:

Please, enter 10 numbers, for example, from 1 to 100!
Enter number #1: a
Invalid Input! Try again!
Enter number #1: 10.5
Invalid Input! Try again!
Enter number #1: 10
Enter number #2: 2
Enter number #3: d
Invalid Input! Try again!
Enter number #3: 4
Enter number #4: 5
Enter number #5: 6
Enter number #6: 7
Enter number #7: 8
Enter number #8: 9
Enter number #9: 10
Enter number #10: 12
Thank you, your total is 73

Note that you must never close Scanner for System.in as it also closes System.in and there is no way to open System.in again.

Arvind Kumar Avinash
  • 50,121
  • 5
  • 26
  • 72