Alan Farrell
Alan Farrell

Reputation: 1

Java - How to Validate Numerical User Input Within A Certain Range Correctly

Just looking for a little help! I am working on a weight conversion program at the moment. I have it working correctly but now I'm trying to make it fool proof, i.e. if a user inputs a numerical value either below or over a certain range (in this case I'm looking for KG between the range of 0 and 450) a message will appear advising of the mistake and will then prompt the user to input their value again. I can do that with the following code but the problem is when the user inputs a valid value it will print the conversion of not only the valid input but also the previous incorrect value. I have attached a screenshot of Command Prompt demonstrationg the issue. Can someone please tell me where I'm going wrong? Thanks.

public void kgToStonesAndPounds()
    {
    double kg = 0;
        
        
        System.out.println("Please enter weight in KG here, range must be between 1 and 450: ");
        kg = input.nextDouble();
        
        
        if ( kg >= 1 && kg <= 450 ) // validate kg
         System.out.printf("\nThe weight you have entered is %.0f KG\n" , kg);
        else
        {System.out.println( "Weight in KG must be in the range of 1 - 450" );
        this.kgToStonesAndPounds();
        }
      
      
        double pounds = kg * 2.204622;

        double stonesWithDecimal = pounds / 14;

        int stone = (int) stonesWithDecimal; // cast int to get rid of the decimal
        
        long poundsWithoutStone = (long)((stonesWithDecimal - stone) * 14); // Take the fractional remainder and multiply by 14
        
        System.out.println("This converts to " + stone + " Stone " + poundsWithoutStone + " Pounds " );
    }//end method kgToStonesAndPounds

EXAMPLE IN COMMAND PROMPT

Upvotes: 0

Views: 68

Answers (4)

bluezealot
bluezealot

Reputation: 119

Both Ausgefuchster and azro' answer work, I give my answer as additional one for discuss. I think most of your code works fine, but you should struct your code more clearly. For the if statement and else statement has no common code to execute, thus all code in the method should be seperate into different branches. Like the following:

public void kgToStonesAndPounds()
    {
    double kg = 0;
        
        
        System.out.println("Please enter weight in KG here, range must be between 1 and 450: ");
        kg = input.nextDouble();
        
        
        if ( kg >= 1 && kg <= 450 ){ // validate kg
         System.out.printf("\nThe weight you have entered is %.0f KG\n" , kg);

      
        double pounds = kg * 2.204622;

        double stonesWithDecimal = pounds / 14;

        int stone = (int) stonesWithDecimal; // cast int to get rid of the decimal
        
        long poundsWithoutStone = (long)((stonesWithDecimal - stone) * 14); // Take the fractional remainder and multiply by 14
        
        System.out.println("This converts to " + stone + " Stone " + poundsWithoutStone + " Pounds " );
        }
        else
        {System.out.println( "Weight in KG must be in the range of 1 - 450" );
        this.kgToStonesAndPounds();
        }
      
    }//end method kgToStonesAndPounds

The reason that led to this problem is that after recursive execution of kgToStonesAndPounds completes, the code will continue to run the rest codes which follow the else block.

Upvotes: 0

WJS
WJS

Reputation: 40057

Java - How to Validate Numerical User Input Within A Certain Range Correctly

As long as you get the desired effect/result (sans bad side effects), one way is no more correct than another.

Here is how I might do it. Just prompt initially and then repeat the prompt if the input isn't correct.

double kg;
String prompt = "Please enter weight in KG here, range must be between 1 and 450: ";
System.out.println(prompt);
while ((kg = input.nextDouble()) < 1 || kg > 450) {
    System.out.println(prompt);
}
System.out.printf("\nThe weight you have entered is %.0f KG\n" , kg);
// now do something with kg

Upvotes: 1

Ausgefuchster
Ausgefuchster

Reputation: 1178

You have to add a return after you call the method again in the invalid case. That way when returning from the method call if it was called from this method it won't move out of else statement and execute the following code.

public void kgToStonesAndPounds() {
    ...

    if ( kg >= 1 && kg <= 450 ) // validate kg
        System.out.printf("\nThe weight you have entered is %.0f KG\n" , kg);
    else {
        System.out.println( "Weight in KG must be in the range of 1 - 450");
        this.kgToStonesAndPounds();
        return; // here
    }
    
    ...
}

Upvotes: 1

azro
azro

Reputation: 54168

Recursion (call a method inside itself) isn't a way to handle errors, it should only be used when the logic requires it.

To ask again, use a loop that will exits only when the input is valid

double kg;
do {
    System.out.println("Please enter weight in KG here, range must be between 1 and 450: ");
    kg = input.nextDouble();
    if (kg >= 1 && kg <= 450) {
        System.out.printf("\nThe weight you have entered is %.0f KG\n", kg);
        break;
    } else {
        System.out.println("Weight in KG must be in the range of 1 - 450");
    }
} while (true);

And you can use modulo to simplify your code

double pounds = kg * 2.204622;
int stone = (int) pounds / 14;
int poundsWithoutStone = (int) pounds % 14;
System.out.println("This converts to " + stone + " Stone " + poundsWithoutStone + " Pounds ");

Upvotes: 0

Related Questions