Ensuring user input is a double? - java

When using scanner is there a way to check that the user input is what we expect?
Say I want a double but the user enters a String what can I do to prompt the user to re-enter the value as a double?
With the following code if a number is not entered I get a mismatchException. I don't want the program to crash if the input is wrong.
Here is my code:
import java.util.Scanner;
public class RoundingNumbers {
private double y;
private double x;
public RoundingNumbers(){
double y = 0;
double x = 0;
}
public void getNumber(){
System.out.print("Enter a decimal number: ");
Scanner num = new Scanner(System.in);
x = num.nextDouble();
}
public void roundNum(){
y = Math.floor(x + 0.5);
}
public void displayNums(){
System.out.println("The actual number is: " + x);
System.out.println("The rounded number is: " + y);
}
}

You can wrap it in a try catch block. See the below example function.
Whoops. I wasn't paying close enough attention and didn't see your code example.
Change your getNumber() function to the below definition. Note that there are many different ways to do this. This is just an example.
public void getNumber(){
Scanner num = new Scanner(System.in);
while(true) {
System.out.print("Enter a decimal number: ");
try {
x = num.nextDouble();
break;
catch(InputMismatchException e) {}
}
}

You already noticed that you recieve a InputMismatchException if they don't type what you expect. With this in mind, you can surround the x = num.nextDouble() with a try-catch block and check for that kind of Exception. For example:
while (true) {
try {
x = num.nextDouble();
// move along if no exception is thrown
break;
} catch (InputMismatchException e) {
// give the user an error message
System.out.println("Type mismatch when reading your input. Please insert a double: ");
}
}
By the way, this is not directly related to your question, but you shouldn't name your Scanner variable as num, because that name doesn't make anyone think of a Scanner - people in general would think it's an int or something. It's a good programming practice to give your variables names that fits them.

Related

how to loop, to ask user input for this Java program?

at this program once the exception is caught, the program displays the catch message and program terminates successfully by itself (I need to run the program again manually if want to ask the user input). I dont want the program to finish but automatically it should ask the user to enter a valid number and performs the functions from the beginning, how to write for this?
import java.util.InputMismatchException;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
try {
System.out.println("Enter a Whole Number to divide: ");
int x = sc.nextInt();
System.out.println("Enter a Whole number to divide by: ");
int y = sc.nextInt();
int z = x / y;
System.out.println("Result is: " + z);
}
catch (Exception e) {
System.out.println("Input a valid number");
}
finally{
sc.close();
}
}
}
Output
Enter a Whole Number to divide:
5
Enter a Whole number to divide by:
a
Input a valid number
Process finished with exit code 0
There are some issues with nextInt that you need to be careful about, You can check out this link: Scanner is skipping nextLine() after using next() or nextFoo()?.
For your program, use a while loop, and you need to be aware of Y could be 0, which would cause an ArithmeticException.
while (true) {
try {
System.out.println("Enter a Whole Number to divide: ");
// use nextLine instead of nextInt
int x = Integer.parseInt(sc.nextLine());
System.out.println("Enter a Whole number to divide by: ");
int y = Integer.parseInt(sc.nextLine());
if (y == 0) {
System.out.println("divisor can not be 0");
continue;
}
double z = ((double) x) / y
System.out.println("Result is: " + z);
break;
}
catch (Exception e) {
System.out.println("Input a valid number");
}
}
sc.close();

Only allow double inputs with java scanner

import java.util.Scanner;
import java.io.*;
public class Positive {
public static void main (String args[]) {
double first;
Scanner scan = new Scanner(System.in);
System.out.print("Please enter first value" + "\n");
first= scan.nextDouble();
if (first>0.00) {
System.out.println("Please enter second value");
}
else if (first <0.00) {
first =-first;
System.out.println(first);
System.out.println("Please enter second value");
}
double second;
Scanner scaning = new Scanner(System.in);
second = scan.nextDouble();
if (first>second) {
System.out.println(first-second);
}
else if (second>first) {
System.out.println(second-first);
}
}
}
Task:
If the value is positive, request a second value. Print the difference between these two numbers so that the difference is always positive. For instance, if the first value is 10.3 and the second is 4.1, you would print the result of 6.2. If the first value is 3.8 and the second is 13.4 you would print the result 9.6.
If the first value read is negative, print its positive equivalent. For instance, if its value is –89.6 you should print 89.6.
If the first value is not a number, give appropriate error message (The standard error message from Java (e.g. “Exception in thread "main” ...”) does not count! Have a look at the Java API or Stack Overflow how to approach this).
The rest of the code runs correctly but I don't know how to only include double values in the input
By using Scanner::nextDouble you are forcing the input to only be doubles, but if you were to use Scanner::nextLine then you could then try to convert to a double and if that fails then print the message
Scanner scan = new Scanner(System.in);
System.out.println("Enter double");
String line = scan.nextLine();
double firstNum = 0.00;
try {
firstNum = Double.parseDouble(line);
}
catch (NumberFormatException e) {
System.err.println("Not a double");
}
Also, rather than doing
if (first>second) {
System.out.println(first-second);
}
else if (second>first) {
System.out.println(second-first);
}
it would be easier to do
System.out.println (Math.abs(first - second));
and also you should remove this line as it is not necessary and you are not even using it
Scanner scaning = new Scanner(System.in);

Methods for Functions

Note: Desire to move this to Code Review with a clearer structure for answer and my modified code which was very similar to the answer besides calcmin method.
I'm trying to break this code up into multiple methods and I was successful with the first bit but the other two I can't seem to figure out.
With the second method I was trying to make it so it would ask the user for an integer and continually prompts them until a proper integer is entered.
With the third method I was trying to make it so that it takes three integer parameters and returns the minimum value of those parameters.
I'd really appreciate the help on this. I've looked through examples in my book and can't seem to get it.
My code:
import java.util.Scanner;
public class MinOfThreeInts
{
public static void intro ()
{
System.out.println("This program determines the minimum of three ints");
System.out.println("It gracefully reports errors when erroneous data is entered ");
System.out.println("For example, if you type in 'abc' when this program asked for an int");
System.out.println("the program will report the error & ask for another int");
System.out.println("Try giving it bad input ! \n\n");
}
public static void readInt (int value1, int value2, int value3)
{
System.out.print(" Please enter an integer value ");
Scanner console = new Scanner(System.in);
String input = console.nextLine();
Boolean goodInt;
int parsedValue = 0;
goodInt = false;
while (!goodInt)
{
try
{
parsedValue = Integer.parseInt(input);
goodInt = true;
}
catch(NumberFormatException ex)
{
System.out.print(" Invalid input, please enter Int ");
input = console.nextLine();
}
}
value1 = parsedValue;
// Get the second integer
System.out.print(" Please enter an integer value ");
input = console.nextLine();
goodInt = false;
while (!goodInt)
{
try
{
parsedValue = Integer.parseInt(input);
goodInt = true;
}
catch(NumberFormatException ex)
{
System.out.print(" Invalid input, please enter Int ");
input = console.nextLine();
}
}
value2 = parsedValue;
// Get the third integer
System.out.print(" Please enter an integer value ");
input = console.nextLine();
goodInt = false;
while (!goodInt)
{
try
{
parsedValue = Integer.parseInt(input);
goodInt = true;
}
catch(NumberFormatException ex)
{
System.out.print(" Invalid input, please enter Int ");
input = console.nextLine();
}
}
value3 = parsedValue;
}
public static void calcMin (min)
{
int min = value1;
if (value2 < min)
{
min = value2;
}
if (value3 < min)
{
min = value3;
}
// Now report the results
System.out.println(" The minimum value of the three ints is " + min);
}
public static void main(String[] args)
{
value1 = readInt(console);
value2 = readInt(console);
value3 = readInt(console);
min = calcMin(value1,value2,value3);
}
}
You have a couple of issues. I refactored your code and added comments, I stayed close to your code in order to give you insights on where you can improve.
First, the code:
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
public class MinOfThreeInts {
//the main method, things start here
public static void main(String[] args) {
//initialize a new scanner that the application will use
Scanner console = new Scanner(System.in);
//print the intro
intro();
//read the values one by one and save them in a variable
int value1 = readInt(console);
int value2 = readInt(console);
int value3 = readInt(console);
//calculate the minimum and save it in the min variable
int min = calcMin(Arrays.asList(value1,value2,value3));
// Now report the results
System.out.println(" The minimum value of the three ints is " + min);
}
/**
* Reads an integer from the given console
*/
public static int readInt(Scanner console) {
System.out.print(" Please enter an integer value ");
//read the input
int parsedValue = 0;
boolean goodInt = false;
//as long as we don't find a valid number
while (!goodInt)
{
try
{
//read the input
String input = console.nextLine();
//try to parse the value
parsedValue = Integer.parseInt(input);
//set goodInt to true so that the while loop will end
goodInt = true;
}
catch(NumberFormatException ex)
{
//if the provivded value was not an integer, print a message and return to the start of the while loop
System.out.print(" Invalid input, please enter Int ");
}
}
return parsedValue;
}
/**
* calculates the minimum of a list of values
*/
public static int calcMin (List<Integer> values) {
//find the minimum and return the value
return Collections.min(values);
}
/**
* prints an intro message
*/
public static void intro () {
System.out.println("This program determines the minimum of three ints");
System.out.println("It gracefully reports errors when erroneous data is entered ");
System.out.println("For example, if you type in 'abc' when this program asked for an int");
System.out.println("the program will report the error & ask for another int");
System.out.println("Try giving it bad input ! \n\n");
}
}
Now, on what you can do to improve:
compile the code does not compile, always take care your code compiles and then slightly edit it until it compiles again
scope your code has multiple declared integers, the problem was that the values were not visible in other methods, if you declare a variable, say int value1 in some method, another method will not be able to see it. If you have another int value1 in that other method, it will only be visible in that specific method and it will actually be another variable
arguments vs return types methods take arguments and return something. The arguments are the input of the method and the returned value is the result of the method. Take for example your method: public static void readInt (int value1, int value2, int value3). This is a method that should read an integer value from the console. However, this method signature says it takes 3 integers as parameter. These integers would be passed by value, since they are primitive types, so you can not pass them, then fill them and then return them. There is also no return type, so the method is not returning something. Since the integer parameters value1, value2 and value3 are only visible in the method scope, you will loose your data. Compare with the new signature: public static int readInt(Scanner console). This method takes a console to read from as a parameter and returns an integer, the number that has been read. This method encapsulates the retry.

Java scanner adding variable conditions

I'd like to ask how do i exactly condition what my program does if my user types in a character or a string if i want him to type an integer instead? I tried to do it how i showed here in quotes and also tried with "equals". The second method didn't work the first seems to be behaving strangely the IF part works but ELSE is completely ignored.
public static void main(String[] args){
Scanner input=new Scanner(System.in);
System.out.print("Enter first integer: ");
int number1 = input.nextInt();// prompt
if (number1 == (char)number1){
System.out.println("Ok.");
}
else{
System.out.println("You were supposed to type in an int..");
System.exit(1);
}
System.out.print("Enter second integer: ");
int number2 = input.nextInt();// prompt
int sum =(number1 + number2);
System.out.printf("Your sum is: %d%n", sum);
}
I suggest you to use the regular expression in the hasNext() function as follows to have a finer control, for example use the following pattern if you look for the numbers,
sc.hasNext("[0-9]+")
Here is the documentation for the hasNext(String pattern) function,
public boolean hasNext(Pattern pattern)
Returns true if the next complete token matches the specified pattern. A complete token is prefixed and postfixed by input that matches the delimiter pattern. This method may block while waiting for input. The scanner does not advance past any input.
Here is the simple code to perform the check,
Scanner sc=new Scanner(System.in);
int input = 0;
while(true) {
System.out.println("enter a number");
if(sc.hasNext("[0-9]+")) {
input = sc.nextInt();
break;
} else {
System.out.println("not a number, try again");
sc.next(); // just consume, but ignore as its not a number
}
}
System.out.println("Entered number is : "+input);
You can use a user defined function as shown below and call it
public static boolean isNum(String input)
{
try
{
int d = Integer.parseInt(input);
}
catch(NumberFormatException e)
{
return false;
}
return true;
}
Then you can call this method from your main function.
if(isNum(number1))
I am not sure if I understand your question, but I see this as follows:
Users will always type a sequence of characters from the input, then your program has to check if that String can be converted to Int, if it can not be converted it should prompt back to the user telling the typed data is not an int. In that case your nextInt will throw an InputMismatchException.
Probably a much more elegant solution is to use hasNextInt(10):
public static void main(String[] args){
Scanner input=new Scanner(System.in);
System.out.print("Enter first integer: ");
if (input.hasNextInt(10)){
System.out.println("Ok. Typed number: " + input.nextInt());
}else{
System.out.println("You were supposed to type in an int..");
System.exit(1);
}
[...]
}
Try this,
try {
int number1 = sc.nextInt();// prompt
System.out.println("Ok.");
} catch (InputMismatchException ex) {
System.out.println("You were supposed to type in an int..");
System.exit(1);
}
Scanner.nextInt(); Scans the next token of the input as an int.
Program won't execute beyond this line if input is not int.
So it will never enter else part. Don't do any int validation.
I would suggest always use try/catch block to handle incorrect input and show useful message. Also don't forget to close Scanner object.

Why am I getting InputMismatchException?

So far I have this:
public double checkValueWithin(int min, int max) {
double num;
Scanner reader = new Scanner(System.in);
num = reader.nextDouble();
while (num < min || num > max) {
System.out.print("Invalid. Re-enter number: ");
num = reader.nextDouble();
}
return num;
}
and this:
public void askForMarks() {
double marks[] = new double[student];
int index = 0;
Scanner reader = new Scanner(System.in);
while (index < student) {
System.out.print("Please enter a mark (0..30): ");
marks[index] = (double) checkValueWithin(0, 30);
index++;
}
}
When I test this, it can't take double number and I got this message:
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:909)
at java.util.Scanner.next(Scanner.java:1530)
at java.util.Scanner.nextDouble(Scanner.java:2456)
at MarkingSystem.checkValueWithin(MarkingSystem.java:25)
at MarkingSystem.askForMarks(MarkingSystem.java:44)
at World.main(World.java:6)
Java Result: 1
How do I fix this?
Instead of using a dot, like: 1.2, try to input like this: 1,2.
Here you can see the nature of Scanner:
double nextDouble()
Returns the next token as a double. If the next token is not a float or
is out of range, InputMismatchException is thrown.
Try to catch the exception
try {
// ...
} catch (InputMismatchException e) {
System.out.print(e.getMessage()); //try to find out specific reason.
}
UPDATE
CASE 1
I tried your code and there is nothing wrong with it. Your are getting that error because you must have entered String value. When I entered a numeric value, it runs without any errors. But once I entered String it throw the same Exception which you have mentioned in your question.
CASE 2
You have entered something, which is out of range as I have mentioned above.
I'm really wondering what you could have tried to enter. In my system, it is running perfectly without changing a single line of code. Just copy as it is and try to compile and run it.
import java.util.*;
public class Test {
public static void main(String... args) {
new Test().askForMarks(5);
}
public void askForMarks(int student) {
double marks[] = new double[student];
int index = 0;
Scanner reader = new Scanner(System.in);
while (index < student) {
System.out.print("Please enter a mark (0..30): ");
marks[index] = (double) checkValueWithin(0, 30);
index++;
}
}
public double checkValueWithin(int min, int max) {
double num;
Scanner reader = new Scanner(System.in);
num = reader.nextDouble();
while (num < min || num > max) {
System.out.print("Invalid. Re-enter number: ");
num = reader.nextDouble();
}
return num;
}
}
As you said, you have tried to enter 1.0, 2.8 and etc. Please try with this code.
Note : Please enter number one by one, on separate lines. I mean, enter 2.7, press enter and then enter second number (e.g. 6.7).
I encountered the same problem.
Strange, but the reason was that the object Scanner interprets fractions depending on localization of system.
If the current localization uses a comma to separate parts of the fractions, the fraction with the dot will turn into type String.
Hence the error ...
Since you have the manual user input loop, after the scanner has read your first input it will pass the carriage/return into the next line which will also be read; of course, that is not what you wanted.
You can try this
try {
// ...
} catch (InputMismatchException e) {
reader.next();
}
or alternatively, you can consume that carriage return before reading your next double input by calling
reader.next()
Are you providing write input to the console ?
Scanner reader = new Scanner(System.in);
num = reader.nextDouble();
This is return double if you just enter number like 456.
In case you enter a string or character instead,it will throw java.util.InputMismatchException when it tries to do num = reader.nextDouble() .

Categories

Resources