1

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!

david
  • 997
  • 6
  • 15
Joni
  • 13
  • 3
  • myScanner is an instance of Scanner. It is not an int. can you give a clear description of the problem? – Stultuske Apr 14 '22 at 13:23
  • Logging/ debugging is your friend. – tiborK Apr 14 '22 at 13:27
  • My problem is that ,I've got no idea why I had to input another integer (6) after the first correct one (7), and that I don't know how to fix it. (And I've tried debugging for a while) – Joni Apr 14 '22 at 13:28
  • not sure, but it might be related to this: https://stackoverflow.com/questions/13102045/scanner-is-skipping-nextline-after-using-next-or-nextfoo – Stultuske Apr 14 '22 at 13:30
  • So you need to run as follows: input a number, if it's not between 1 and 200 enter it again and one more time to confirm that. Exit after. Is that correct? – tiborK Apr 14 '22 at 13:31
  • Yes, but before that I need to check if it even is a number. If not, it should require another input. – Joni Apr 14 '22 at 13:32
  • To check if a number is even use the '%' operator. Like: input % 2 == 0. Also, no need for all that while loop, maybe one in this case. Save the first input and use it as a comparison to the next input. Double-check what your code is doing and if it matches your logic. – tiborK Apr 14 '22 at 13:36

1 Answers1

1

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.

Hulk
  • 6,399
  • 1
  • 30
  • 52
  • I tired to use what you showed me in a single method and it worked, thank you very much. I've added the working code the main question now. Thank you very much again! – Joni Apr 14 '22 at 14:18
  • Glad to hear it worked - I've updated the answer to provide an inlined solution as well. – Hulk Apr 15 '22 at 06:35