Mortgage calculator, how to exclude letter and accept only numbers - java

we have this method
System.out.print("Enter Principal Amount (1k to 1m) ") ;
while (true) {
principal = scanner.nextInt();
if (principal >= 1000 && principal <= 1_000_000)
break;
System.out.println("Enter a value between 1k - 1m");
If person puts in letters instead of numbers the error occurs,
I need to get the program to ask the question to put in numbers instead of letter
Scanner scanner = new Scanner(System.in);
System.out.print("Enter Principal Amount (1k to 1m) ") ;
while (true) {
principal = scanner.nextInt();
// if (scanner.nextInt() != NumberFormat??) What should I write in my mortgage calculator that ->
// --> if numbers are not put (for ex. letters) it would print out ("Please enter numbers letters are invalid")
//System.out.println("Please enter numbers");
if (principal >= 1000 && principal <= 1_000_000)
break;
System.out.println("Enter a value between 1k - 1m");
}

The simplest way to do what you want is to wrap the inside of your loop in a try {} block and catch the InputMismatchException
If the input is an int it will process as it does now; if not then instead of carrying on after the Scanner.nextInt() line, java will execute the contents of your catch(InputMismatchException e) { } block
There's an argument that you should validate the input more explicitly, but that will be more complex and for a beginner learning how to catch exceptions is probably more useful.
while (true) {
try {
principal = scanner.nextInt();
if (principal >= 1000 && principal <= 1_000_000)
break;
System.out.println("Enter a value between 1k - 1m");
}
catch (InputMismatchException e) {
System.out.println("Please enter numbers");
}
}

From the comments, the OP replied:
No, if for ex. user enters "abc", I get = Exception in thread "main" java.util.InputMismatchException at java.base/java.util.Scanner.throwFor(Scanner.java:943) at java.base/java.util.Scanner.next(Scanner.java:1598) at java.base/java.util.Scanner.nextInt(Scanner.java:2263) at java.base/java.util.Scanner.nextInt(Scanner.java:2217) at com.petras.Main.main(Main.java:20)
But I want to get the line "Please enter valid number" //not letter and let him put the number again, how should my code look?
The problem is that your code assumes the user will always enter a valid integer value. Instead, as your comment reply indicates, you have to account for invalid inputs by wrapping scanner.nextInt() in a try/catch block
Scanner scanner = new Scanner(System.in);
System.out.print("Enter Principal Amount (1k to 1m) ") ;
int principal = 0;
while (true) {
try {
principal = scanner.nextInt();
} catch(InputMismatchException ime) {
System.out.println("Invalid input: " + principal + ". Please enter an integer value");
continue;
} catch (Exception e) {
// This is most likely a "true" error. Handle accordingly.
}
if (principal >= 1000 && principal <= 1_000_000)
break;
System.out.println("Enter a value between 1k - 1m");
}

Related

How can I remove this java exception error in my code?

When I input a string into the code below by mistake as a test, I get a red java error message in my console. However, within my if statement I added an else part which should end the program if the user doesn't input the if statement condition i.e a number between 0-100. Why this is and how can I fix it?
MY CODE
Scanner input = new Scanner(System.in);
System.out.println("Enter a number: ");
int decimal = input.nextInt();
if (decimal > 0 && decimal <= 100) {
//code
}
else {
System.exit(0);
}
When I input a string this message gets displayed. However, I just wanted to tell the user they exerted the wrong value and I wanted the program to quit.
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:864)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at MainHandler.main(MainHandler.java:22)
I did try use hasNextInt at one point to try get rid of the exception error but I get an error when I use hasNextInt. https://imgur.com/a/OK8r3RH
Try with something like this. You surround your input inside a try-catch and as long as you get an Exception, you ask the user to put a number again. As soon as the input is valid (a number) you can proceed with your code:
boolean canProceed = false;
int number = -1;
while (!canProceed) {
try {
Scanner input = new Scanner(System.in);
System.out.println("Enter a number: ");
number = Integer.parseInt(input.nextLine());
canProceed = true;
} catch (Exception e) {
System.out.println("Invalid input.");
}
}
if (number > 0 && number <= 100) {
System.out.println("That's fine");
}
else {
System.exit(0);
}
You would need double if you are entering decimal numbers and put your code inside try/catch block
try{
Scanner input = new Scanner(System.in);
System.out.println("Enter a number: ");
double decimal = input.nextDouble();
if (decimal > 0 && decimal <= 100) {
}
else {
System.exit(0);
}
}catch (Exception e){
System.out.println(e);
}
Try binding your code inside try and catch blocks like this:
try{
int decimal = input.nextInt();
if (decimal > 0 && decimal <= 100) {
//code
}
else {
System.exit(0);
}
}
catch(Exception e){
System.out.println("You enter wrong value");
}
The code you posted works just fine if the input is provided from the start. However given your "Enter a number:" message I suppose you want the user to provide the input interactively, in which case you'll have to implement a waiting loop :
Scanner input = new Scanner(System.in);
System.out.println("Enter a number: ");
while (!scanner.hasNextInt()) {
if (scanner.hasNextLine()) {
scanner.nextLine(); // we've got something but it's not a number, discard it
}
}
int decimal = input.nextInt();
if (decimal > 0 && decimal <= 100) {
//code
}
else {
System.exit(0);
}
In this case the loop will continue until it finds an integer to read from the input, discarding lines of input if they don't start with an integer.
I just thought I would throw this in here since it is another flexible alternative to accomplishing the task. It utilizes the Scanner#nextLine() method with input validation to ensure that what is supplied is actually what is expected without the worry of an exception being thrown.
Validation is done using the String#matches() method supplied with a small Regular Expression (RegEx) to insist that numerical digits are supplied and that the supplied value is within the desired inclusive unsigned numerical range of 1 to 100. If the validation fails then the User is expected to try again or enter 'Q' (or anything that starts with Q - case insensitive) to quit.
Scanner input = new Scanner(System.in);
int intValue = 0;
String numberString = "";
// Prompt and Input...
while (intValue == 0) {
System.out.print("Enter a number (or 'q' to quit): --> ");
numberString = input.nextLine().toLowerCase();
//Quit..
if (numberString.charAt(0) == 'q') {
System.exit(0);
}
// Integer (unsigned - Range 1 to 100)...
else if (numberString.matches("100|[1-9][0-9]{1}?")) {
intValue = Integer.parseInt(numberString);
}
else {
System.err.println("Invalid numerical value supplied or the supplied");
System.err.println("value is not in the inclusive range of 1 to 100!");
System.err.println("Try Again...");
System.err.println();
}
}
//Your processing code here.
System.out.println("The value you entered is: --> " + intValue);
Explanation for the RegEx used within the String#matches() method:
100|[1-9][0-9]{1}?
1st Alternative 100
100 matches the characters 100 literally (case sensitive)
2nd Alternative [1-9][0-9]{1}?
Match a single character present in the list below [1-9]
1-9 a single character in the range between 1 (index 49) and 9 (index 57) (case sensitive)
Match a single character present in the list below [0-9]{1}?
{1}? Quantifier — Matches exactly one time (meaningless quantifier)
0-9 a single character in the range between 0 (index 48) and 9 (index 57) (case sensitive)
If you want to change your numerical range then you may find this site useful.

How to return to the previous statement after catching an error instead of restarting the whole program in Java?

I recently started learning Java as I have a keen interest in programming. I am currently creating an application that calculates a person's BMI.
Question: Is there a way to return to the previous statement when the user has made a mistake on instead of restarting the whole program (EG: when the line Please enter your weight in pounds executed, the user input a non-integer value and an error prompts out saying Invalid Input, it will then return to the previous line that the user made an error -> Please enter your weight in pounds executed).
If yes, how so?
import java.util.Scanner;
import java.text.DecimalFormat;
public class Body_Mass_Calculation {
private static int gender, inputAnswer;
private static boolean wenttocatch;
private static double myBMI, heightInch, weightPound, weightKilo, heightMeter;
private static Scanner input_1 = new Scanner(System.in);
private static DecimalFormat df2 = new DecimalFormat("#.##");
//Questions + Calculation
static void myMethod() {
try {
System.out.println("Please enter gender. 1-- Male 2--Female");
gender = input_1.nextInt();
while (gender > 2 || gender < 1) {
System.out.println("Invalid input!");
System.out.println("Please enter gender. 1-- Male 2--Female");
gender = input_1.nextInt();
}
if (gender == 1 || gender == 2) {
System.out.println("Please enter your height in inches. ");
heightInch = input_1.nextInt();
System.out.println("Please enter your weight in pounds. ");
weightPound = input_1.nextInt();
heightMeter = heightInch * 0.0254;
weightKilo = weightPound * 0.45359237;
myBMI = weightKilo / (heightMeter * heightMeter);
}
if (gender == 1) {
if (myBMI >= 27.8)
System.out.println("Your body-mass-index is " + df2.format(myBMI) + " this is considered high ! \n \n");
else
System.out.println("Your body-mass-index is " + df2.format(myBMI) + " this is not considered high ! \n \n");
}
if (gender == 2) {
if (myBMI >= 27.3)
System.out.println("Your body-mass-index is " + df2.format(myBMI) + " this is considered high ! \n \n");
else
System.out.println("Your body-mass-index is " + df2.format(myBMI) + " this is not considered high! \n \n");
}
System.out.println("Do you wish to continue? Enter: 1 -> Yes, 2 -> No.");
inputAnswer = input_1.nextInt();
System.out.println("Invalid Input !");
if (inputAnswer == 2) { //If input = 2, Program executes line below
System.out.println("Thank You for using this shitty app !");
System.exit(2);
} else if (inputAnswer == 1) {
myMethod();
}
} catch
(Exception e) {
input_1.next();
wenttocatch = true;
System.out.println("Invalid input !");
input_1.nextLine();
myMethod();
}
}
public static void main(String[] args) {
//Executes Function/Method
System.out.println("Welcome ! \n ");
myMethod();
}
}
No, you can't. The solution is to write a method that takes care of it. Instead of writing a ton of code and repeating yourself, you use a method to encapsulate some functionality, so that you can invoke it a lot without copying code. For example, instead of:
System.out.println("Please enter gender. 1-- Male 2--Female");
gender = input_1.nextInt();
while (gender > 2 || gender < 1) {
System.out.println("Invalid input!");
gender = input_1.nextInt();
}
you really just want to write something like:
gender = askInt("Please enter gender. 1-- Male 2-- Female", 1, 2);
where the askInt is a method you write which takes the text you want to show as prompt, along with the smallest and largest valid value.
Now that you have this function, you can expand its functionalities and all the code that uses this function gets the functionality automatically. So, if you add 'catch invalid input exceptions and re-ask' functionality to this one method, ALL the questions get it.
int askInt(String prompt, int min, int max) {
int result;
while (true) {
System.out.println(prompt);
result = input.nextInt();
if (result >= min && result <= max) return result;
System.out.println("Invalid input!");
}
}
This basic loop will keep looping until the if clause is triggered, causing the method to return, which is the only way out. You can now add handling for NumberFormatException within this one method, within the while loop. You can't go back to the line that caused the problem, but you can go forward, and in a while loop, going forward automatically jumps back to the start (i.e., that's how to go 'backwards'). So, we mix a while loop (which can go backwards) and a catch block, and that's how to solve the problem. And then we put all this in a method, so that we can write this code only once, instead of having to repeat it every time.
You can do it by using a do { _code1 } while (_condition) which execute the _code until _condition is false.
And _code1 is a try {}catch which will catch any exception (error) thrown from inside the try {} block.Here the exception (error) is thrown if the user enters a character instead of a digit.
System.out.println("Please enter gender. 1-- Male 2--Female");
int gender = 0 ;
do {
try {
if (gender == -1) {
System.out.println("Invalid input!");
System.out.println("Please enter gender. 1-- Male 2--Female");
}
gender = input_1.nextInt () ;
}catch (Exception e){
gender = -1 ;
}
}while (gender > 2 || gender < 1);

Continue prompting till criteria fulfiled

I am practicing exception handling and have more or less grasp the basic concept.
I have been searching up on how to continue execution by prompting user to input the value which fulfills the specific criteria despite catching the exception by using a loop
I have this specific code that request user to enter a value between a range and have an exception handling to catch if a string is being input-ed. However, the program stops executing after it prints out the exception handling.
Any ideas how I can implement a loop or any other method that can continue the program execution after exception handling?
Scanner scanner = new Scanner(System.in);
int num = 0;
try
{
System.out.print("Please enter a number between 1 to 50 : ");
num = scanner.nextInt();
}
catch (InputMismatchException e) {
System.out.println("Not a number");
return;
}
while (num > 50 || num < 1) {
System.out.print("Out of range. Enter a number between 1 to 50 : ");
num = scanner.nextInt();
}
System.out.println("The number is : " + num);
Exceptions should handle exceptional situations, i.e. situations you couldn't anticipate in advance. Since you can definitely anticipate that the user may enter invalid input, you can handle that invalid input without any exception handling :
Scanner scanner = new Scanner(System.in);
int num = 0;
while (num > 50 || num < 1) {
System.out.print("\nPlease enter a number between 1 to 50 : ");
while (!scanner.hasNextInt()) {
scanner.next(); // discard non-integer inputs
System.out.print("\nPlease enter a number between 1 to 50 : ");
}
num = scanner.nextInt();
}
System.out.println("You entered " + num);
Sample output :
Please enter a number between 1 to 50 : -1
Please enter a number between 1 to 50 : 53
Please enter a number between 1 to 50 : ff
Please enter a number between 1 to 50 : rr rr ff
Please enter a number between 1 to 50 :
Please enter a number between 1 to 50 :
Please enter a number between 1 to 50 : 13
You entered 13
Note that this code is much shorter than the version that uses exception handling.
Use this:
Scanner scanner = new Scanner(System.in);
boolean isInputValid = false; // input flag, valid = true / invalid = false
int num = 0;
while(!isInputValid) {
try
{
System.out.print("Please enter a number between 1 to 50 : ");
num = scanner.nextInt();
// Input is a valid integer
if (!(num > 0 && num < 51)) { // input out of range
System.out.print("Out of range.");
}
else
isInputValid = true; // input valid, proceed & break loop
}
catch (InputMismatchException ex) { // input not an integer
System.out.println("Not a number");
scanner.next();
}
catch (Exception ex) {
ex.printStackTrace();
}
}
System.out.println("The number is : " + num);

Try-Catch inside a loop

In the below code, I ask the user to give an integer input and if the input is 0 or a negative number, it loops again until the positive number is given. The thing is that if the users presses a letter, my code crashes and despite the fact that I used try-catch in a lot of ways nothing really worked. Any ideas?
I used try-catch inside the loop, but it only worked for one letter input and not correctly.
System.out.print("Enter the number of people: ");
numberOfPeople = input.nextInt();
while (numberOfPeople <= 0) {
System.out.print("Wrong input! Enter the number of people again: ");
numberOfPeople = input.nextInt();
}
The problem in your current code is that you're always trying to read an int so when receiving a non-integer input you can't handle the error in the right way. Modify this to always read a String and convert it into an int:
int numberOfPeople = 0;
while (numberOfPeople <= 0) {
try {
System.out.print("Enter the number of people: ");
numberOfPeople = Integer.parseInt(input.nextLine());
} catch (Exception e) {
System.out.print("Wrong input!");
numberOfPeople = 0;
}
}
//continue with your life...

Set boundaries for integer input

I have this small snippet of coding that requires an input from the user when it is ran to determine a certain value. I don't want the user to be able to enter anything less than 0 and anything greater than 1 million, so, 0 =< YEARS_AHEAD =< 1000000.
I've looked through so many tutorials and searched for help on this and found nothing. This is my code.
Scanner reader = new Scanner(System.in);
int YEARS_AHEAD;
System.out.print("Enter the amount of years ahead: ");
while (true)
try {
YEARS_AHEAD = Integer.parseInt(reader.nextLine());
break;
}catch (NumberFormatException nfe) {
System.out.print("This value must be an integer, please enter the number of years ahead again: ");
}
Add a simple if:
if (YEARS_AHEAD < 0 || YEARS_AHEAD > 1000000) {
// say something to the user, retry entering the number
}
Another option is to use the while cycle for this:
int YEARS_AHEAD = -1; // invalid value
while (YEARS_AHEAD < 0 || YEARS_AHEAD > 1000000) {
try {
System.out.print("Enter the amount of years ahead: ");
YEARS_AHEAD = Integer.parseInt(reader.nextLine());
}catch (NumberFormatException nfe) {
System.out.print("This value must be an integer, please enter the number of years ahead again: ");
}
}
Once you have read the input
YEARS_AHEAD = Integer.parseInt(reader.nextLine());
check using if-else whether the input is permitted or not.
if(YEARS_AHEAD < 0 || YEARS_AHEAD >1000000){
System.out.println("Invalid Input");
}else{
// do your processing here.
}

Categories

Resources