Input validation checking if the input is a double - java

I want to check if the input I entered is the correct data type. For example if the user enters an int when I want them to enter a double then the program tells them there is an error. This is what I have so far:
System.out.println("Enter the temperature in double:");
String temp = input.nextLine();
try
{
Double temperature = Double.parseDouble(temp);
}
catch(Exception e)
{
isValid = false;
System.out.println("Temperature must be a double ");
}
All its doing is continuing on through the program and not printing out the error message when I enter an int. Been stuck on this for a while so any help would be appreciated.

I think you are looking to validate only decimal numbers (not including integers). If that is the case then you can use a regex for the same :
System.out.println("Enter the temperature in double:");
String temp = input.nextLine();
while (temp != null && !temp.matches("^[0-9]*\\.([0-9]+)+$")) { // use of regex here
System.out.println("Enter the temperature in double:");
temp = input.nextLine(); // read input again
}
This will loop until the user gives in only a valid decimal input. Explanation of this regex.

Since you don't want int to get accepted, you can just add an if to check whether the input String has a decimal point or not.
System.out.println("Enter the temperature in double:");
String temp = (new Scanner(System.in)).next();
if (temp.contains(".")) {
try {
Double temperature = Double.parseDouble(temp);
} catch(Exception e) {
isValid = false;
System.out.println("Temperature must be a double ");
}
} else {
isValid = false;
System.out.println("Temperature must be a double ");
}

Related

How to loop wrong data type inputs? [duplicate]

This question already has an answer here:
While loop to determine if entered value is a double
(1 answer)
Closed 1 year ago.
I know there are lots of questions similar to this but I can't understand most of it, also I can't see any similar questions related to java language.
So can you guys help me how to loop this question if the input is not a double data type?
The code:
System.out.println("Enter first number");
num1 = input.nextDouble();
System.out.println("Enter second number");
num2 = input.nextDouble();
I really appreciate anyone who tries to answer, tia!!
This is a solution (without exception handling). It loops until two Doubles have been entered. So it is possible to enter this:
3
4.2
or also:
www
3
abc
4.2
Both will give the same result
3
4.2
Note that the code is locale sensitive in regard of the numbers you enter at the command prompt (meaning that the decimal sign depends on your computer settings – in Germany for example it is the comma and not the dot, so you would enter 4,2):
Scanner scanner = new Scanner(System.in);
Double part1 = null;
Double part2 = null;
while (true) {
if (scanner.hasNextDouble()) {
if (part1 == null ) {
part1 = scanner.nextDouble();
} else {
part2 = scanner.nextDouble();
break;
}
} else {
scanner.next(); // The input is not a Double, so just drop it
}
}
scanner.close();
System.out.println(part1);
System.out.println(part2);
If you add the line scanner.useLocale(Locale.ROOT) after creating the scanner:
Scanner scanner = new Scanner(System.in);
scanner.useLocale(Locale.ROOT);
the decimal sign will be the dot '.' like in 4.2 independent of the settings of your computer.
I like to create a separate method to validate input. If the value is invalid, then I have the method return -1. Then I'll have a while loop that checks if the input is -1, if so, than it'll ask the for a new input value till it's correct. There are many ways to go about it. But the gist is something like this.
public static void main(String[] Args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter first number");
double num1 = validateDouble(input);
while (num1 == -1) {
num1 = validateDouble(input);
}
System.out.println(num1);
}
private static double validateDouble(Scanner scanner) {
String input = scanner.nextLine();
try {
double i = Double.parseDouble(input);;
return i;
}catch (InputMismatchException | NumberFormatException e) {
if (input.equals("q")) {
System.exit(0);
}
System.out.println("Please try again.");
return -1;
}
}

How to Repeat `try` Block for Specific Cases?

I have a program here that accepts a numeric value (stored as a BigDecimal) and the currency (USD or CNY) stored as a String. With the help of user dimo414, I was able to account for blank inputs and non-numeric inputs, while also allowing the user to retry until a valid input is read.
Here is the code:
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter the amount of money and specify"
+ " currency (USD or CNY): ");
Boolean invalidInput; // breaks out of do-while loop after successful outcome
do {
invalidInput = false;
try {
String line = input.nextLine();
Scanner lineScan = new Scanner(line);
BigDecimal moneyInput = lineScan.nextBigDecimal();
String currency = lineScan.next();
if (currency.equals("USD")) {
// convert USD to CNY
} else if (currency.equals("CNY")) {
// convert CNY to USD
} else {
/*
reprompt user for currency,
but retain the value of moneyInput;
repeat process until valid currency
*/
}
} catch (NoSuchElementException | IllegalStateException e) {
// deals with errors:
// non-numeric moneyInput or blank input
}
} while (invalidInput);
}
Now I'm having trouble dealing with when moneyInput is valid, but currency is not, e.g. 100.00 abc. In this case, I'd like to prompt the user to re-enter a value for currency while retaining the value of money.
I tried using a similar do-while loop around the section that prompted for currency and continued onto the if-else block like so:
do {
String currency = lineScan.next();
if (currency.equals("USD")) {
// convert USD to CNY
} else if (currency.equals("CNY")) {
// convert CNY to USD
} else {
invalidInput = true;
System.out.print("Please enter a valid currency: ");
// since invalidInput == true,
// jump back up to the top of the do block
// reprompt for currency
}
} while (invalidInput);
But this solution was ineffective because it would display the exception error message from the outer catch block, so I'd actually have to implement a do-while loop inside a try-catch block inside a try-catch block, and that got messy really fast.
I also tried defining a new function outside of main called readCurrency that I could invoke in the else block, but I ran into issues of variable scopes. I am still a beginner in Java so I didn't know how to properly define a function and pass the necessary info to it.
What other ways are there to loop back up to the top of that try block and allow the user to re-enter the currency only?
Thanks so much for reading and providing feedback.
You are mixing input validation with processing. Do one thing at a time, first validate, then process. With a little bit of code modularization using helpers, this becomes simple enough.
String amountString;
String currencyString;
do {
System.out.println("Please insert a valid amount and currency");
String line = input.readLine();
String[] values = line.split("\\s"); //split on the space
amountString = values[0];
currencyString = values[1];
}
while (!isValidAmount(amountString));
while (!isValidCurrencyString(currencyString) {
System.out.println("Amount accepted but unsupported currency. Please input only the correct currency now");
currencyString = input.nextLine();
}
Now what you need are the helpers method:
boolean isValidAmount(String amountString)
boolean isValidCurrency(String currencyString)
Once you have them, and have completed the validation, you can actually insert the processing logic:
BigDecimal amount = BigDecimal.parse(amountString); //this may be the wrong name of the parse function, don't remember but something like that;
switch(currencyString) {
case "USD": //...
}
Can you write the helper methods yourself? They should be easy :)
What i was suggesting in the comment is to split the retrieval of the amount and the one for the currency, so you can develop different solutions, and different loops to each of them. I made a quick example. Hope it helps:
Main method
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
BigDecimal moneyInput = getMoneyInput(input);
String currencyInput = getCurrency(input);
System.out.println(moneyInput.toString() + " " + currencyInput);
}
GetCurency function
public static String getCurrency(Scanner input) {
System.out.print("Enter the currency: ");
String currency = null;
boolean invalidInput = true;
try {
do {
String line = input.nextLine();
if ("USD".equals(line) || "CNY".equals(line)) {
invalidInput = false;
currency = line;
} else {
System.out.print("Invalid currency, enter it again please");
}
} while (invalidInput);
} catch (Exception e) {
System.out.println(e.getMessage());
System.out.print("Invalid currency, enter it again please");
}
return currency;
}
GetAmount function
public static BigDecimal getMoneyInput(Scanner input) {
System.out.print("Enter the amount of money without the currency: ");
BigDecimal moneyInput = BigDecimal.ZERO;
boolean invalidInput = true;
try {
do {
String line = input.nextLine();
moneyInput = new BigDecimal(line);
invalidInput = false;
} while (invalidInput);
} catch (Exception e) {
System.out.println(e.getMessage());
System.out.print("Invalid input, enter it again please");
}
return moneyInput;
}
Ok, so some restructuring was required to get the code working.
The input object is used to fetch values from console.
The currency value is fetched inside a loop (do-while), where the loop condition is that currency should not be equal to 'USD' or 'CNY'. This eliminates the need for invalidInput loop variable.
public static void main(String[] args) {
try {
Scanner input = new Scanner(System.in);
System.out.print("Enter the amount of money and specify"
+ " currency (USD or CNY): ");
//Boolean invalidInput; // Not required
//String line = input.nextLine();
//Scanner lineScan = new Scanner(line);
String currency =null;
BigDecimal moneyInput = input.nextBigDecimal();
do{
if(currency!=null){
System.out.print("Please enter a valid currency: ");
}
currency = input.next();
}while(!currency.equals("USD")&&!currency.equals("CNY"));
if (currency.equals("USD")) {
// convert USD to CNY
} else if (currency.equals("CNY")) {
// convert CNY to USD
}
} catch (NoSuchElementException | IllegalStateException e) {
// deals with errors:
// non-numeric moneyInput or blank input
}
}
Here you go:
public void main(String[] args){
Scanner input = new Scanner(System.in);
String message = "Enter the amount of money and specify currency (USD or CNY)";
System.out.println(message);
boolean invalidInput = true;
BigDecimal moneyInput = null;
String currency = null;
do{
try{
String line = input.nextLine();
Scanner lineScan = new Scanner(line);
BigDecimal temp = lineScan.nextBigDecimal();
if(temp == null){
if(moneyInput == null){
System.out.println(message);
continue;
}
}else{
moneyInput = temp;
}
String tempCurrency = lineScan.next().toUpperCase();
if(!temp.isValid()){
if(currency == null){
System.out.println("Reenter currency:");
continue;
}
}else{
currency = tempCurrency;
}
if (currency.equals("USD")) {
// convert USD to CNY
} else {
// convert CNY to USD
}
invalidInput = false;
}catch(Exception e){
System.out.println(message);
moneyInput = null;
}
}while(invalidInput);
}
You also need to add this method:
public boolean isValid(String currency){
return currency.equals("USD") || currency.equals("CNY");
}
This will go on until both values are valid and will not force the user re-enter another BigDecimal if a valid one has already been supplied, but it will allow the user to change the BigDecimal every time the currency is invalid.

How do you check that the user entered a String value instead of a number?

I wrote a simple program that calculates the hypotenuse of a triangle when the user inputs side A and B. I have a while loop that prompts the user to enter a value greater than 0 if they do, but how do I check if the user enters a String value?
while (sideA<=0 || sideB<=0){
What should I add so if the user enters a string value, the loop will also start?
Thanks
However you get your input (from command line, scanner or buffered reader) first parse it and try to store it in an integer variable. If its a string, then catch the exception and allow the user to enter the value again.
try
{
int sideA = Integer.parseInt(input);
}
catch (NumberFormatException ex)
{
//Do something here to keep continuing the while loop
}
Scanner input = new Scanner(System.in);
// requesting user input
System.out.println("Enter x and y : ");
String x = input.next();
String y = input.next();
try {
double d1 = Double.parseDouble(s1);
double d2 = Double.parseDouble(s2);
if(d1 > 0 && d2 > 0) {
//Call for the hypotenuse method
double z = hypotenuse(d1,d2);
}
} catch (NumberFormatException e) {
System.out.println("Invalid Input!");
}
you can use the binary instanceof operator. it returns a boolean value in this manner:
if( myVariable instanceof String )
//it's a string!
else
//it's not a string
This approach can of course be used to check for other types as well. I recommend type checking your A and B variables as strings using instanceof and handle accordingly

Handling Exceptions in Java - How to give user another chance?

Hey guys so i've been trying to answer this question for hours:
Write a program that asks the user to input a set of floating-point values. When the
user enters a value that is not a number, give the user a second chance to enter the
value. After two chances, quit reading input. Add all correctly specified values and
print the sum when the user is done entering data. Use exception handling to detect
improper inputs.
I've tried a few different things but i always have the same problem. Once something that isn't a number is given as input, the program outputs the message prompting for another input however the chance is not given, that is to say after 1 incorrect input it prints that message and jumps straight to printing the sum. The best i could do is below i'm just not sure how to approach this problem. Any help is greatly appreciated.
import java.util.Scanner;
import java.util.InputMismatchException;
public class q6{
public static void main(String[] args){
Scanner in = new Scanner(System.in);
boolean firstChance = true;
boolean secondChance = true;
double sum = 0;
while (secondChance){
try{
while (firstChance){
try{
System.out.print("Please enter a number: ");
double input = in.nextDouble();
sum = sum + input;
}
catch (InputMismatchException ex){
firstChance = false;
}
System.out.print("Please enter a number to continue or something else to terminate: ");
double input = in.nextDouble();
sum = sum + input;
firstChance = true;
}
}
catch (InputMismatchException e){
secondChance = false;
}
}
System.out.print("The sum of the entered values is " + sum);
}
}
i'm just not sure how to approach this problem
Pseudocode could be as follows:
BEGIN
MAX_INPUT = 2;
i = 0;
WHILE i < MAX_INPUT
TRY
num = GET_NUM();
CATCH
continue;
FINALLY
i++
END WHILE
END
Since the parsing of input to double is not successful, the scanner does not go past the given input. From javadoc Scanner
Scans the next token of the input as a double. This method will throw
InputMismatchException if the next token cannot be translated into a
valid double value. If the translation is successful, the scanner
advances past the input that matched.
Since the translation is not successful, it does not advance. So, in the catch block you could call in.next() to skip the token.
You could use an integer counter instead of the boolean variables firstChance and secondChance and do something like:
int attempts = 0;
while(attempts < 2) {
try {
//Get user input - possible exception point
//Print sum
} catch(InputMismatchException e) {
attempts++;
//Continue?
}
}
import java.util.*;
public class q6 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
double inputNumber, sum = 0.0;
int correctCount = 0, wrongCount = 0;
while(wrongCount <=1) {
System.out.println("Please enter a numeric floating value:");
try {
inputNumber = in.nextDouble();
correctCount++;
sum += inputNumber;
if(correctCount >= 2)
break;
} catch(InputMismatchException e) {
wrongCount++;
in = new Scanner(System.in);
continue;
}
}
System.out.println(sum);
}
}
You need to break your while loop when you encounter a "bad" input. Then, you'll need to set firstChance to true again, so you can access the second while, you also will need a counter that counts the number of the attempts (I named it chances):
int chances = 0;
while (secondChance){
firstChance = true;
try{
while (firstChance){
try{
System.out.print("Please enter a number: ");
double input = in.nextDouble();
sum = sum + input;
}
catch (InputMismatchException ex){
chances ++;
in = new Scanner(System.in);
firstChance = false;
}
if(!firstChance && chances < 2)
break;
if(chances >= 2) {
System.out.print("Please enter a number to continue or something else to terminate: ");
double input = in.nextDouble();
sum = sum + input;
firstChance = true;
}
}
}
catch (InputMismatchException e){
secondChance = false;
}
}
As stated in my comment, in order to not deal with Scanner wrong read, it would be better to use Scanner#nextLine() and read the data as String, then try to parse it as double using Double#parseDouble(String) since this method already throws NumberFormatException and you can handle this error. Also, it would be better that your code could handle more than 1 request (if your teacher or somebody else asks to do this):
final int REQUEST_TIMES = 2;
double sum = 0;
for(int i = 1; i <= REQUEST_TIMES; i++) {
while (true) {
try {
if (i < REQUEST_TIMES) {
System.out.print("Please enter a number: ");
} else {
System.out.print("Please enter a number to continue or something else to terminate: ");
}
String stringInput = in.nextLine();
double input = Double.parseDouble(stringInput);
sum += input;
} catch (NumberFormatException nfe) {
System.out.println("You haven't entered a valid number.");
break;
}
}
}
The logic is to read the input once, if it is correct then display the sum, else read the input again and display the sum if the input is correct.
public class q6 {
static int trial = 0;
public static void main(String[] args) {
double sum = 0;
while (trial <= 2) {
Scanner in = new Scanner(System.in);
try {
trial++;
System.out.print("Please enter a number: ");
double input = in.nextDouble();
sum = sum + input;
trial=3;
} catch (InputMismatchException ex) {
trial++;
if (trial == 4){
System.out.println("You have entered wrong values twice");
}
}
}
if (trial <= 3){
System.out.print("The sum of the entered values is " + sum);
}
}
The above program is just a rough idea, you can improve this to adapt to your need.

How to tell my if-statement to only accept integers?

I want my program to tell the user that if (s)he enters a non-integer he should try again, instead of just terminating the whole main method like it does now. Pseudo code of problem part:
int integer = input.nextInt();
If (user types in a non-integer) {
("you have entered a false value, please retry");
then let's user enter int value
else {
assign nextint() to integer and continue
}
You can use a while loop to re-execute that portion of code until the user enters a proper integer value.
do {
input = read user input
} while(input is not an integer)
It seems you are using a Scanner, so you could use the hasNextInt method:
while (!input.hasNextInt()) {
let user know that you are unhappy
input.next(); //consume the non integer entry
}
//once here, you know that you have an int, so read it
int number = input.nextInt();
This is assuming that you are worried about the user entering in something other than an integer on input:
public static void main(String[] args) {
Integer integer = 0;
Scanner sc = new Scanner(System.in);
System.out.println("Enter an integer:");
String line = sc.next();
integer = tryParse(line);
while(integer == null){
System.out.print("The input format was incorrect, enter again:");
integer = tryParse(sc.next());
}
int value = integer.intValue();
}
public static Integer tryParse(String text){
try{
return new Integer(text);
} catch
(NumberFormatException e){
return null;
}
}

Categories