I’m having trouble with my code.
What it should do:
- Check if Scanner “myScanner” is an Integer
- If it is an Integer, if it is between 1 and 200 (both included)
Problem:
- I need to input an Integer with the correct value twice after the the first guess wasn’t correct.
Here is a screenshot of exactly what I mean: Screenshot of the problem
private static int inputGuess () { Scanner myScanner = new Scanner(System.in); int guess = 0; if (myScanner.hasNextInt()) { guess = myScanner.nextInt(); } if (1 > guess || guess > 200) { while (!(myScanner.hasNextInt()) || !(1 <= guess && guess <= 200)) { while (!myScanner.hasNextInt()) { myScanner.nextLine(); } guess = myScanner.nextInt(); if (!(guess >= 1 && guess <= 200)) { myScanner.nextLine(); } } } return guess; }
I have tried to apply @Hulk’s (top answer) logic (at least I think I did) into a single method (is sadly a requirement for my project) and got this:
private static int inputGuess () { Scanner myScanner = new Scanner(System.in); int guess = 0; while (!myScanner.hasNextInt() || guess < 1 || guess > 200) { while (!myScanner.hasNextInt()) { myScanner.nextLine(); } guess = myScanner.nextInt(); if (guess >= 1 && guess <= 200) { break; } } return guess; }
After a bit of testing still no error! If you still find a mistake I would be happy if you shared it with me!
Advertisement
Answer
This gets a lot simpler if you split your problem into smaller parts. First, solve the “read until we got an integer” part and put it into a method so we can reuse it:
private static int readNumber(Scanner sc) { while (!sc.hasNextInt()) { sc.nextLine(); // if its not a number, consume the line and wait for new input } return sc.nextInt(); // always an integer }
Now, we only need to add the range check:
private static int inputGuess () { Scanner myScanner = new Scanner(System.in); int n = 0; while (n < 1 || n > 200) { // range check, only in one place n = readNumber(myScanner); // always returns a number } return n; }
You basically complicated things too much, by repeating the range check in 3 places in different ways, and it’s easy to get lost with all these negations. Keep your methods simple, and only do one thing at a time!
To adress your updated question: If you absolutely need to inline these into one method, this is the result:
private static int inputGuess () { Scanner myScanner = new Scanner(System.in); int n = 0; while (n < 1 || n > 200) { // loop until in valid range while (!myScanner.hasNextInt()) { myScanner.nextLine(); // if its not a number, consume the line and wait for new input } n = myScanner.nextInt(); // always an integer } return n; // always in valid range }
Note that there is still only one place where there is a check for numeric input, and only one place where the range is validated. In programming, there is rarely a reason to write exactly the same thing twice – don’t repeat yourself! – a ‘principle’/guideline sometimes abbreviated as DRY.