Getting a correct input value using scanner

Question!

I've implemented a method that asks the user to enter a value. If said value is out of range or it isn't the correct type of value, it should show an error message and then ask again.

public static Integer getValue (Integer minValue, Integer maxValue) {
    Scanner input;
    input = new Scanner (System.in);
    Integer value;
    value = null;
    while (true) {
        try {
            value = input.nextInt();
            input.nextLine();
            if ((value >= minValue) && (value <= maxValue)) {
                break;
            } else {
                // Shows message that says value is not in range.
                continue;
            }
        } catch (InputMismatchException IME) {
            // Shows message that says value is not an integer.
            input.next();
            continue;
        }
    }
    input.close();
    return(value);
}

The code can identify correctly when it's being given an undesired value. The problem comes when the value is actually correct, then it just hangs and takes me to the debugger.

This is an example of an execution:

Select the type of furniture:
1. - Dresser.
2. - Shelf.
3. - Rectangular table.
4. - Round table.
You chose: abc // Asks again because the value entered is not int.
a b c
adsf
5 // Asks again because the value entered is not in range.
1 // Here it is when the compiler takes me to the debugger.

Here's what happens if i force the execution past this point; it shows me the menu below then it completely crashes after asking the user for another value:

Select the type of wood.
1. - Mahogamy.
2. - Cherry-tree.
3. - Walnut.
4. - Pine tree.
5. - Oak tree.
You chose: 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)

This is how it's being called from main:

furnitureMenu();
indexTree = getValue(minIndexFurniture, maxIndexFurniture);
woodMenu();
indexWood = getValue(minIndexWood, maxIndexWood);

It's crucial that I get this method to work because, as shown above, I'll require an input from the user several other times, and not just to select from menus, but also to get specifications for the furniture such as dimensions and what not.

All help is appreciated. Thanks in advance.



Answers
public static Integer getValue(Integer minValue, Integer maxValue) {
        Scanner input;
        input = new Scanner(System.in);
        int value;
        while (true) {

 System.out.println("Please enter a value");
            if(!input.hasNextInt()) {
                System.out.println("That's not a number!");
                input.next(); // this is important!
            }
            value = input.nextInt();
            if ((value >= minValue) && (value <= maxValue)) {
                return value;
            } else {
                System.out.println("Wrong value please provide a valid input");
            }
        }

    }

Try this. It may help achieving what you want to do.



I already came to a conclusion myself after looking exhaustively for other related questions to mine in this site. This is the one question that solved it: java.util.NoSuchElementException - Scanner reading user input

When you call, sc.close() in first method, it not only closes your scanner but closes your System.in input stream as well.

As seen in my question, my code instantiated a new scanner inside my method, and after a correct value was entered, the method closes the scanner, which prevents new input to be entered after the method is called subsequently.

This is the revision i made:

public static Integer getValue (Scanner input, int minValue, int maxValue) {
    int value;
    value = 0;
    while (true) {
        try {
            value = input.nextInt();
            if((value < minValue) || (value > maxValue)) {
                // ERROR message goes here
            } else {
                break; // Input successful, break loop.
            }
        } catch (InputMismatchException IME) {
            // ERROR message goes here.
            input.nextLine(); // Discards input so user can try again
        }
    }
    return (value);
}

As seen in this revision, the scanner was previously instantiated in the main function and passed as an argument so it can retrieve input from the user inside the method in subsequent calls.

I also improved the way it receives input taking notes from Deitel's book, Java How To Program Chapter 11: Exception Handling, and I adapted it to my specific case.



You can add (almost) 180 before the modulus, and subtract it later.

Not exactly 180 because then you would get -180 instead of 180.

var val = 0;
for(var i=0; i<8; ++i) {
  console.log(val = (val + 90 + 179) % 360 - 179);
}

By : Oriol


This video can help you solving your question :)
By: admin