e.doroskevic e.doroskevic - 3 months ago 14
Java Question

How-to validate user input when using scanner for input gathering

Description



What I am aiming to do is request user to provide an input only to those entries which triggered an exception excluding those input requests which have been satisfactory

Example



Note:
input
is an instance of a
Scanner


public Fluid addFluid() {
do{
try{
System.out.println("Please enter fluids ID: ");
f.setFluidID(input.next());
System.out.println("Please enter fluids molecular weight: ");
f.setMolecularWeight(input.nextDouble());
System.out.println("Please enter fluids temperature: ");
f.setTemperature(input.nextDouble());
error = false;
}
catch(InputMismatchException e){
System.out.println("Error! Please provide the right input.");
// if exception happens on input for setMolecularWeight(input.nextDouble()); skip print statement for fluids ID and f.setFluidID(input.next());
}
}
while(error != false);
getFluid().add(f);
System.out.println(getFluid());
return f;
}


Output



Please enter fluids ID:
propane
Please enter fluids molecular weight:
a
Error! Please provide the right input.
Please enter fluids ID: // how to exclude this print statement
Please enter fluids molecular weight:


Would there be a way how to do this using an
if / else
structure. I would want to avoid doing
try / catch
for every input operator.
Many thanks in advance.

Answer

Short answer:

You'll need clear the buffer on the Scanner after the call to nextDouble(), since your InputStream will contain a newline \n.

Adding input.next(); or input.nextLine(); to the end of your catch blocks should work to skip that extra \n.

(See java.util.Scanner : why my nextDouble() does not prompt?)

Explanation:

  • Even though nextDouble blocks execution until the user enters a newline \n, it only returns characters from Scanner's buffer that are valid characters (characters that will parse correctly to a double). This means
  • if you enter input that doesn't parse to a double, those invalid characters are still sitting in the buffer. When you attempt to read the nextDouble again, it will just repeat the same process on the existing input, resulting in the infinite loop.
  • Therefore, you'll need to "clear" the buffer before continuing. Since there doesn't seem to be a method for this, you'll just need to advance the Scanner to the end of the buffer. In this case, input.next(); will suffice.

(Credits to user jonhopkins for the code I shamelessly grabbed from his answer)

System.out.println("Please enter fluids ID: ");
while (true) {
    try {
        f.setFluidID(input.next());
        break; // break out of the current loop
    } catch (InputMismatchException e) {
        System.out.println("Error! Please provide the right input.");
        input.next();
    }
}

System.out.println("Please enter fluids molecular weight: ");
while (true) {
    try {
        f.setMolecularWeight(input.nextDouble());
        break; // break out of the current loop
    } catch (InputMismatchException e) {
        System.out.println("Error! Please provide the right input.");
        input.next();
    }
}

System.out.println("Please enter fluids temperature: ");
while (true) {
    try {
        f.setTemperature(input.nextDouble());
        break; // break out of the current loop
    } catch (InputMismatchException e) {
        System.out.println("Error! Please provide the right input.");
        input.next();
    }
}

NOTE: You may even need an extra input.next() call before you read the 2nd and 3rd inputs (I haven't tested this).

Comments