I'm trying to create some input validation for incorrect input in my program.
The program is supposed to read the user input as a double but it must display a message that input is not a number if the user types a letter instead of a number.
To do this, I use input.hasNextDouble with an if statement. The else, prints the message that x is not a number. However, my problem lies with the second number that the user inputs. Let's say that the user enters "5 f" The hasNextDouble interprets the double and then executes the code under the if statement, but the input is still incorrect because of the "f".
In short, I need a way for the first input (5) to be removed from the buffer so the second input can be interpreted.
Any help is appreciated!
here is some sample code:
if ( keyboard.hasNextDouble() ) {
double i = keyboard.nextDouble();
double j = keyboard.nextDouble();
double answer = (j+i );
System.out.println(answer);
}
else {
String a = keyboard.next();
String b = keyboard.next();
System.out.println( a + "is not a number");
double i,j, answer;
try{
i = keyboard.nextDouble();
j = keyboard.nextDouble();
answer = i+j;
} catch( InputMismatchException e ) {
// One of the inputs was not a double
System.out.println("Incorrect format");
}
otherwise if you absolutely need to print out which was incorrect, I would just do the if-then you have twice.
double i=null, j=null, answer;
// get input for i
if ( keyboard.hasNextDouble() ) {
i = keyboard.nextDouble();
}else{
System.out.println( keyboard.next() + " is not a double");
}
// get input for j
if ( keyboard.hasNextDouble() ) {
j = keyboard.nextDouble();
}else{
System.out.println( keyboard.next() + " is not a double");
}
// if both i and j received inputs
if( i != null && j != null )
answer = i + j;
else
System.out.println("Malformed input");
You need something like following.
double tryReadDouble(Scanner keyboard) throws NumberFormatException {
if (keyboard.hasNextDouble()) {
return keyboard.nextDouble();
} else {
throw new NumberFormatException(keyboard.next());
}
}
And
try {
double i = tryReadDouble(keyboard);
double j = tryReadDouble(keyboard);
double answer = (j + i);
System.out.println(answer);
} catch (NumberFormatException ex) {
System.out.println(ex.getMessage() + "is not a number");
}
Hope this helps.
You can create helper method which will ask user for valid input, until it gets one, or until some limit of tries will be exceeded. Such method can look like this:
public static double getDouble(Scanner sc, int maxTries) {
int counter = maxTries;
while (counter-- > 0) {// you can also use `while(true)` if you
// don't want to limit numbers of tries
System.out.print("Please write number: ");
if (sc.hasNextDouble()) {
return sc.nextDouble();
} else {
String value = sc.next(); //consume invalid number
System.out.printf(
"%s is not a valid number (you have %d tries left).%n",
value, counter);
}
}
throw new NumberFormatException("Used didn't provide valid float in "
+ maxTries + " turns.");
}
then you can use this method like
Scanner keyboard = new Scanner(System.in);
double i = getDouble(keyboard, 3);
double j = getDouble(keyboard, 3);
double answer = (j + i);
System.out.println(answer);
Related
I'm trying to write a function to validate the user's input. It only returns when the user inputs a double number.
private static double getDouble(String name) {
double res = 0;
Scanner s = new Scanner(System.in);
while (true) {
System.out.println("Please input " + name + ":");
if (s.hasNextDouble()) {
res = s.nextDouble();
break;
}
else s.nextLine();
}
s.close();
return res;
}
However, it only works first time. If I call the function second time right after the first time, the nextLine() will throw an exception.
double length = 0, width = 0;
length = getDouble("length of picture");
width = getDouble("width of picture");
Please see the
Could someone tell me what the mistake I have made here? And how to fix/avoid it?
Thank you.
I have made another way for getting user input. Just refer to the code and code comments for details.
private static double getDouble(String name) {
double res = 0;
Scanner s = new Scanner(System.in);
while (true) {
try {
System.out.print("Please input " + name + ":");
res = Double.parseDouble(s.nextLine()); // Just get the user input as a string then try to convert it into a double
break; // if there is no error in the string to double conversion it means that the input is valid, thus break the loop
} catch (Exception e) { // catch possible errors in case the input is invalid
System.out.println("Your input is invalid!"); // print desired error message then the loop will execute again getting another user input
}
}
s.close();
return res;
}
EDIT
It is because you have close the scanner instance after the method. Refer to this why that won't work. You could also refer to that for alternatives.
If you want to use hasNextDouble then you could either pass the scanner as a parameter to your getDouble method or declare the scanner as a class variable. Both will result to only declaring and closing 1 Scanner.
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
double tmp = getDouble(s, "Tmp");
double tmp2 = getDouble(s, "Tmp");
s.close();
}
private static double getDouble(Scanner s, String name) {
double res = 0;
while (true) {
System.out.println("Please input " + name + ":");
if (s.hasNextDouble()) {
res = s.nextDouble();
break;
} else
s.nextLine();
}
return res;
}
When you close the Scanner object (s.close();) for System.in you can't use scanner again until you restart your application. It's best to leave the Scanner object open until you are absolutely sure you won't need it again.
Personally, I really don't like purposely relying on exceptions to take care of invalid situation but in this case it's extremely suited for it:
private static double getDouble(String name) {
double res = 0.0d;
Scanner s = new Scanner(System.in);
while (res == 0.0d) {
System.out.print("Please input " + name + ": --> ");
try {
res = s.nextDouble();
}
catch (Exception e) {
// If input is invalid
System.out.println("Your input is invalid! Numerical Values Only!");
/* Clear the scanner buffer otherwise the response
above will continue to display over and over
again. */
s.nextLine();
res = 0.0d;
}
}
return res;
}
You can also do this without using an exception trap:
private static double getDouble(String name) {
String res = "";
Scanner s = new Scanner(System.in);
while (res.equals("")) {
System.out.print("Please input " + name + ": ");
res = s.nextLine();
/* If the User supplies anything that is NOT a string
representation of a signed or unsigned integer or
double type numerical value. A regular Expression is
used here with the String#matches() method. */
if (!res.matches("-?\\d+(\\.\\d+)?")) {
// Input is invalid...
System.out.println("Your input is invalid (" + res + ")! Only Integer or Double Type Numerical Values Are Allowed!");
res = "";
}
}
return Double.parseDouble(res);
}
// The program compiles and runs as it should to compute averages I am just struggling to add negative, and double values to it.
import java.util.*;
public class DoWhileLoops {
public static void main (String [] args) {
Scanner kb = new Scanner(System.in);
int sum = 0,
ct = 0;
String input = "";
do {
System.out.println
("Enter a positive whole number, or q to quit.");
int n=0, sct=0;
char c;
input = kb.nextLine();
do {
c = input.charAt(sct);
if (c >= '0' && c <= '9')
{
n = n * 10;
n += (int)(c - '0');
}
sct++;
} while (sct < input.length());
if (n > 0) {
sum += n;
ct++;
}
} while (!input.equalsIgnoreCase("q"));
System.out.printf("The sum of the %d numbers you entered is: %d\n", ct, sum);
if(ct > 0)
System.out.printf("The average is: %.2f", (double)sum/ct);
else
System.out.printf("No numbers entered - can't compute average");
}
}
//Need help having the program so it will recognize positive and negative values as well as doubles.
You use a Regular Expression (regex) within a String#matches() method to determine if the User has entered a string representation of a valid number of either a signed (negative) or unsigned (positive) integer or double data type value, for example:
if (!input.matches("-?\\d+(\\.\\d+)?")) {
System.err.println("Invalid numerical value supplied! Try again..." + ls);
continue;
}
The regular expression used in the matches() method above is: "-?\\d+(\\.\\d+)?" and here is an explanation of what it means:
When summing, you want to use a double data type variable which means then that when the User supplies a value we want to parse it to a double data type. To do this you can use the Double.parseDouble() method to convert the string numerical value to a double data type and add that value to our summation (the sum variable which we've already declared as double).
Here is what the code might look like:
Scanner kb = new Scanner(System.in);
String ls = System.lineSeparator();
double sum = 0;
int counter = 0;
String input;
do {
System.out.print((counter + 1) + ") Enter a numerical value (or q to finish): ");
input = kb.nextLine();
// If the first character supplied by User is a Q then exit loop
if (Character.toString(input.charAt(0)).equalsIgnoreCase("q")) {
break;
}
// If the value supplied is not a numerical value
// then inform User and let him/her/it try again.
if (!input.matches("-?\\d+(\\.\\d+)?")) {
System.err.println("Invalid numerical value supplied! Try again..." + ls);
continue;
}
counter++;
double num = Double.parseDouble(input);
sum += num;
} while (true); // q must be given to exit loop.
System.out.printf(ls + "The sum of the %d numbers you entered is: %f\n", counter, sum);
if (counter > 0) {
System.out.printf("The average is: %.2f", (double) sum / counter);
}
else {
System.out.printf("No numerical values entered! - Can not compute average!");
}
So my biggest problem is that I cannot seem to remember how to parse a string into an int so that I can idiot proof my code. My goal here is to find out if the user enters in a word instead of an int and then I can explain to them what an integer is. Can someone please help? I just need a simple list of parsing commands so that I can study them for use in the future, once there is a simple list I think I'll be able to figure all the others out from there.
import java.util.Scanner;
import java.util.*;
public class SelfTestNumberNine
{
public static void main(String[] args)
{
boolean test = false;
int num = 0;
int sum = 0;
int count = 0;
int pos = 0;
int neg = 0;
Scanner in = new Scanner(System.in);
while(!test)
{
num = 0;
System.out.print("Enter in an Integer Value: ");
String letta = in.next();
if(??parsing stuff goes here!!)
{
num = in.nextInt();
count++;
if(num > 0)
{
pos++;
sum = sum + num;
}
else if(num < 0)
{
neg++;
sum = num + sum;
}
else
{
test = true;
}
}
else
{
System.out.println("An Integer is a number that is positive or
negative,\nand does not include a decimal point.");
}
}//end while
System.out.println("Total: " + sum);
double avg = sum / count;
System.out.println("Average: " + avg);
}//end main
}//end class
Basically, the program asks the user to input integers, counts the number of positive and negatives, and prints out the total and average (Ignoring 0). The program ends when the user inputs a 0.
P.S. Thanks for your time!! ]:-)
If you want to ensure that the user has entered an int without throwing an exception if they don't you can use the hasNextInt() method:
System.out.println("Enter an int (0) to quit");
//While the user has not entered a valid int
while (!input.hasNextInt()) {
System.out.println("Please enter an integer: ");
//Consume the bad input
input.nextLine();
}
Which will loop until they enter a valid int. A sample run (- denotes user input):
Enter an int (0 to quit)
-No
Please enter an integer:
-Never!!
Please enter an integer:
-Ok ok fine
Please enter an integer:
-3
You can do this in two ways.
- Integer.parseInt()
- Integer.valueOf()
String myStr = "1";
int parsedInt = Integer.parseInt(myStr);
int valueOf = Integer.valueOf(myStr);
System.out.println("Parse Int: " + parsedInt);
System.out.println("Value Of: " + valueOf);
Note: You might get exception if the input is not parseable. NumberFormatException.
You can use a Boolean method and a try-catch to check if you can parse the string to an Integer.
public static boolean isInteger(String s) {
try {
Integer.parseInt(s);
} catch(NumberFormatException e) {
return false;
} catch(NullPointerException e) {
return false;
}
// only got here if we didn't return false
return true;
}
The program asks for the user input for the double num 1 and double num 2
and if there is an exception I want it to ask again for the input of num 1 and num 2
public static void main (String[] args) {
Scanner sc = new Scanner(System.in);
double num1, num2;
int error = 0;
int text;
System.out.print("Enter 4 ");
text = sc.nextInt();
do{
try{
if(text == 4){
System.out.print("Enter number 1: ");
num1 = sc.nextDouble();
System.out.print("Enter number 2: ");
num2 = sc.nextDouble();
double quotient = num1/num2;
System.out.println("The Quotient of "+num1 + "/" +num2+ " = "+quotient);
}
}catch(Exception ex){
System.out.println("You've entered wrong input");
error = 1;
}
}while(error == 1);
}
then when I try the code if it will catch the exceptions by inputing string in the num1 or num 2 I'm having this infinite loop :
Enter number 1: You've entered wrong input
Enter number 1: You've entered wrong input
Enter number 1: You've entered wrong input
Enter number 1: You've entered wrong input
Enter number 1: You've entered wrong input
You need to reset the error variable inside the loop
do {
error = 0;
//...
} while(error == 1);
It is not necessary to utilize exception handling. Just use Scanner.hasNextDouble() method to find out if actual user input is double, otherwise continue the cycle.
package com.company;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
double num1, num2;
num1 = readDouble(1, sc);
num2 = readDouble(2, sc);
double quotient = num1/num2;
System.out.println("The Quotient of " + num1 + "/" + num2 + " = " + quotient);
}
private static double readDouble(int i, Scanner sc) {
while (true) {
System.out.print("Enter number " + i + ": ");
if (!sc.hasNextDouble()) {
System.out.println("You've entered wrong input");
sc.next();
continue;
}
break;
}
return sc.nextDouble();
}
}
Its in C# but relatively similar :)
public class Program
{
private static double ReadUserInput (string message)
{
// This is a double
// The '?' makes it nullable which is easier to work with
double? input = null;
do
{
// Write message out
Console.Write(message);
// Read answer
var inputString = Console.ReadLine();
// Temp variable for the number
double outputNumber = 0;
// Try parse the number
if (double.TryParse(inputString, out outputNumber))
{
// The number was parsable as a double so lets set the input variable
input = outputNumber;
}
else
{
// Tell the user the number was invalid
Console.WriteLine("Sorry bud, but '" + inputString + "' is not a valid double");
}
}
while (input == null); // Keep running until the input variable is actually set by the above
// Return the output
return (double)input;
}
public static void Main()
{
// Read a number
var num1 = ReadUserInput("Enter number 1:");
// Read another number
var num2 = ReadUserInput("Enter number 2:");
// Show the calculation
Console.WriteLine("Answer: " + (num1*num2));
}
}
Demo
And for the actual code (in JAVA):
public class JavaFiddle
{
public static void main (String[] args)
{
// Read a number
Double num1 = ReadUserInput("Enter number 1:");
// Read another number
Double num2 = ReadUserInput("Enter number 2:");
// Show the calculation
System.out.println("Answer: " + (num1*num2));
}
public static Double ReadUserInput (String message)
{
java.util.Scanner inputScanner = new java.util.Scanner(System.in);
Double input = null;
do
{
// Write message out
System.out.println(message);
// Read answer
String inputString = inputScanner.nextLine();
try
{
// Try parse the number
input = Double.parseDouble(inputString);
}
catch (NumberFormatException e)
{
// Tell the user the number was invalid
System.out.println("Sorry bud, but '" + inputString + "' is not a valid double");
}
}
while (input == null); // Keep running until the input variable is actually set by the above
// Return the output
return input;
}
}
You probably want to test if there is no error:
}while(error != 1);
or
}while(error == 0);
You'll need a method for the input which calls itself, if the input is invalid.
double getInput(Scanner sc) {
try {
double num = sc.nextDouble();
return num;
} catch(Exception ex) {
System.out.println("You've entered wrong input");
return getInput(sc);
}
}
And call this method twice in your other method.
it may look ugly , but here is a way to do it
do
{
if(...)
{
boolean successReading = false;
while(!successReading)
{
try
{
System.out.print("Enter number 1: ");
num1 = sc.nextDouble();
System.out.print("Enter number 2: ");
num2 = sc.nextDouble();
successReading = true;
double product = num1*num2;
}
catch(Exception e)
{
successReading = false;
}
}
}
}while(...)
You need to add sc.next(); inside catch block.
nextDouble method doesn't clear buffer in case of exception. So next time you invoke it you get same error because old input is still in buffer.
Also you need to reset your error flag in the beginning of the loop.
You have to put sc.next(); in the catch so it will clear your scanner variable and it will ask for an input
This question already has answers here:
How to handle infinite loop caused by invalid input (InputMismatchException) using Scanner
(5 answers)
Closed 5 years ago.
i added a while loop so that if the user enters an invalid value, the code will re-prompt the user to put in a valid value. but the when the user puts in an invalid value, the code goes in an infinite loop. any help would be much appreciated !!
public static void main(String[] args) {
System.out.println("Usage : enter a, b, & c from a quadratic equation");
System.out.println(" aX^2 +bX + c = 0");
System.out.println(" Result will be 2 values for X");
Scanner in = new Scanner(System.in);
double a = 0;
double b = 0;
double c = 0;
double x1 = 0 ;
double x2 = 0;
double discriminant = 0;
System.out.println("Please enter values for a , b, and c ");
while(true){
try
{
a = in.nextDouble();
break;
}
catch(java.util.InputMismatchException E)
{
System.out.println("wrong input, try again");
}
}
while(true){
try
{
b = in.nextDouble();
break;
}
catch(java.util.InputMismatchException E)
{
System.out.println("wrong input, try again");
}
}
while(true){
try
{
c = in.nextDouble();
break;
}
catch(java.util.InputMismatchException E)
{
System.out.println("wrong input, try again");
}
}
//x1 = (-b+sqrt(b*b - 4ac))/2a
//x2 = (-b+sqrt(b*b - 4ac))/2a
discriminant = b*b -4.0 * a * c;
x1 = (-b + Math.sqrt(discriminant))/2.0*a;
x2 = (-b - Math.sqrt(discriminant))/2.0*a;
System.out.println("The two values for X are " + x1 + " and " + x2);
}
When the nextDouble method throws an InputMismatchException, it doesn't consume the bad input that caused the exception.
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.
You should advance beyond the bad input, or else nextDouble will continue to read the same bad input over and over again.
Consume the bad input and discard it with in.next(), e.g.:
catch(java.util.InputMismatchException E)
{
in.next();
System.out.println("wrong input, try again");
}
The above suggested will work. However, you need to check the discriminant. You are not handling the case when discriminant is less than zero. You will get NaN as the roots if the discriminant is negative. Please refer to Math.sqrt() documentation for more details.
//x1 = (-b+sqrt(b*b - 4ac))/2a
//x2 = (-b+sqrt(b*b - 4ac))/2a
discriminant = b*b -4.0 * a * c;
x1 = (-b + Math.sqrt(discriminant))/2.0*a;
x2 = (-b - Math.sqrt(discriminant))/2.0*a;