Warm tip: This article is reproduced from serverfault.com, please click

Loops and user input validation in java, again

发布于 2020-11-29 00:39:54

So, I think about two days back I asked a question about input validation, and how to loop programs until the user gave a valid input..

So I made a calculator and I wanted to loop every step of the program so that if the user didn't put a double (69, 42.0) or the appropriate operator char (/, *, +, -) they would be stuck on that step till they got it right or otherwise closed the app entirely.

So one thing I got from the last question about this is that I could make a boolean value called "restart" or something and encapsulate my entire code except for the main method obviously and at the end I could make a question that they could answer true or false and the entire app could run again. While I admit having a "start over" button on my app is cool and useful for all my other a projects (probably not, I'm sure this can be done more efficiently), It still didn't satiate me and my original problem.

SO...

I got to trying everything I could (I know stack likes people who show that they at least tried).

EXAMPLE 1

Scanner input = new Scanner(System.in);

        double valX;
        
            System.out.println("Calculator Activated.");

                do
                {
                    System.out.print("Value X: ");
                    valX = input.nextDouble();
                }while (!input.hasNextDouble());
                {
                    System.out.println("Invalid number!");
                }
//Didn't work ¯\_(ツ)_/¯

EXAMPLE 2

Scanner input = new Scanner(System.in);

        double valX;

            System.out.println("Calculator Activated.");

            while (!input.hasNextDouble())
            {
                System.out.println("Value X: ");
                valX = input.nextDouble();
            }
//neither this one...

Note that the solution you guys give me has to apply to every step of the program.

And for a bit more clarity is the entire src code without the stuff I tried and the "restart" loop.

import java.util.Scanner;

public class CalTest
{
    public static void main(String[] args)
    {
        Scanner input = new Scanner(System.in);

        double valX, valY, divided, multiplied, added, subtracted;  //Declared all my variables...
        char operator;
        boolean restart; //Didn't need to declare it true or false since I'm using a Scanner anyway

        do //Start of the entire program
        {
            System.out.println("Calculator Activated.");

            System.out.print("Value X: "); //I need a loop here...
            valX = input.nextDouble();
            
            System.out.print("Operator: "); //And here...
            operator = input.next().charAt(0);

            System.out.print("Value Y: "); //And here too..
            valY = input.nextDouble();

            divided = valX / valY;
            multiplied = valX * valY;
            added = valX + valY;
            subtracted = valX - valY;

            if (operator == '/')
                System.out.println("Result: " + divided );
            else if (operator == '*')
                System.out.println("Result: " + multiplied); //<--Not sure if I need a loop with the if's
            else if (operator == '+')
                System.out.println("Result: " + added);
            else if (operator == '-')
                System.out.println("Result: " + subtracted);
            else
                System.out.println("Invalid operator!");

            System.out.print("Try again? "); //I also need a loop here, I think.
            restart = input.nextBoolean();

        } while (restart); //End of it if you declared false.
        
        System.out.println("Calculator terminated.");
    }
}

At one point I tried to use the same "restart the app" concept and made a boolean variable for every single step in the code and it honestly was tiresome and not worth it.

Also I'm just a beginner if it's a concept of the loops that I'm missing then I'm happy to learn it from you guys.

Again, gracias to anyone who answers and helps contribute to my learning.

Questioner
Nod
Viewed
0
Robert Bain 2020-11-29 09:32:10

In your final code example in the class called CalTest where you assign valX = input.nextDouble(); you could a call recursive method that handles the exception until the input is what you want. Something like this:

private static double getNextDouble(Scanner input) {
    try {
        return input.nextDouble();
    } catch (InputMismatchException e) {
        System.out.println("Value X must be a number: ");
        input.next();
        return getNextDouble(input);
    }
}

You'll replace valX = input.nextDouble(); with valX = getNextDouble(input);.

You can tidy this up and make it work for your other potential error cases, perhaps creating a parameter for the output message and passing it in as an argument.