try catch in a do while loop - java

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

Related

types cannot be converted when validating the users input for an integer

I am trying to validate a user's input and check if the inputted number is an integer. Id like to throw them an error message if the number isn't an integer. I am getting stuck on the line Integer.parseInt(number); Any suggestions would be very appreciated.
import java.util.Scanner;
public class Sums {
public static int number;
public static void main(String[] args) {
int evenSum, oddSum = 0;
int posInt;
Scanner input = new Scanner(System.in);
System.out.println("Enter a postitive integer: ");
int number = input.nextInt();
try {
Integer.parseInt(number);
System.out.println("Value entered is " + number);
} catch (NumberFormatException e) {
System.out.println(number + " is not an integer.");
}
}
}
I have changed the int number = input.nextInt(); to String number = input.next(); and it works.
The issue here is that when you call Integer.parseInt(number) you are trying to parse the variable number which is an int and not a String. This means that you are doing the error checking on a conversion from an int to an Integer and not a String to an Integer.
To fix this, input a string instead of a number, then perform the conversion on the string, not the number.
...
public static void main(String[] args) {
int myNumber;
Scanner input = new Scanner(System.in);
System.out.println("Enter a postitive integer: ");
String numberString = input.nextLine();
try {
myNumber = Integer.parseInt(number);
System.out.println("Value entered is " + myNumber);
// do what you want with the number
} catch (NumberFormatException e) {
System.out.println(numberString + " is not an integer.");
}
}
...
You don't need explicitly to convert your number to an integer, Scanner.nextInt() already does that for you, i.e. Scanner.nextInt() scans the next token of the input as an int. So just remove the line "int number = input.nextInt();" from your code. In general, Integer.parseInt() is preferable when you want to convert a String representation of an Integer value as a signed decimal integer. For instance, if you would have used Scanner.nextLine() instead of Scanner.nextInt(), then it makes more sense to convert it to a signed decimal integer if you want to perform subsequent operations using that integer value.
int number = input.nextInt();
The variable number is already an int, that is why you can not hand it over to the method. The method requires a String.
If you want to use the method like you did, you should use
input.next()
as argument because it returns the input as String and initialize number within the try block, e.g.
public static void main(String[] args) {
int evenSum, oddSum = 0;
int posInt;
System.out.println("Enter a postitive integer: ");
Scanner input = new Scanner(System.in);
try {
number = Integer.parseInt(input.next());
System.out.println("Value entered is " + number);
} catch (NumberFormatException e) {
System.out.println("Not an integer.");
}
}
Bug here is int number = input.nextInt();
When you want to convert a String to a primitive datatype we use class.parseXXX(String)
You see I have written String in the function .parseXXX(String) Cause it takes String as a parameter and nothing else
So lets read your code
Integer.parseInt(number);
Here its .parseXXX(int) and clearly its not matching .parseXXX(String)
So in order to give String as parameter, you have accept String as input from user.
Replace this int number = input.nextInt(); with String number = input.next();
So now below code is valid cause its in .parseXXX(String)
Integer.parseInt(number);
Changed code:
int evenSum, oddSum = 0;
int posInt;
Scanner input = new Scanner(System.in);
System.out.println("Enter a postitive integer: ");
String number = input.next(); // <-- Changed
try {
Integer.parseInt(number);
System.out.println("Value entered is " + number);
} catch (NumberFormatException e) {
System.out.println(number + " is not an integer.");
}

Java Exception problem with scanner and method

I've got some problems in java with putting scanner after an output, in a while loop.
the scanner scans which method to go and then when it comes back to the start of the loop
reset the variable.
I've already tried this and failed to find any understandable solution (I'm really new to java, and it is hard for me),
or to solve it myself.
here is the full code (i know the code is not so efficient):
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int con = 1;
System.out.println("Hey!,welcome to my games!");
Scanner scanner = new Scanner(System.in);
String game;
while (con == 1) {
System.out.println(
"Here Some games i have(Enter the text for the one you want):\nto stop=0\n1)calculator=1\n2)!Soon! Random numbers");
game = scanner.nextLine();
calculator();
scanner.reset();
System.out.println(game);
// if(game.equals("0")) {
// con=0;
// }
// else if(game.equals("1")) {
// System.out.println("Welcome Back!");
// }
// else {
// System.out.println("There is a mistake in your text");
// }
}
scanner.close();
}
static void calculator() {
int num1, num2, con = 1, stop = 1;
String op, ad = "add", su = "sub", mul = "multi", di = "div";
Scanner af = new Scanner(System.in);
while (con == 1) {
stop = 1;
System.out.println("Write number 1");
num1 = af.nextInt();
System.out.println("Write number 2");
num2 = af.nextInt();
System.out.println(
"Write an operation (one of these):\nAddition=add\nSubtraction=sub\nMultiplication=multi\nDivision=div");
op = af.next();
op = op.toLowerCase();
int minus = num1 - num2;
int plus = num1 + num2;
if (op.equals(ad)) {
System.out.println("The Operation is:Addition\n" + num1 + "+" + num2 + "=" + plus);
} else if (op.equals(su)) {
System.out.println("The Operation is:Subtraction\n" + num1 + "-" + num2 + "=" + minus);
} else if (op.equals(mul)) {
System.out.println("The Operation is:Multiplication\n" + num1 + "*" + num2 + "=" + num1 * num2);
} else if (op.equals(di)) {
System.out.println("The Operation is:Division\n" + num1 + "/" + num2 + "=" + num1 / num2);
} else {
System.out.println("Um,Did you make a mistake in your text?\nDo you want the calculator again?");
String yn = af.next();
yn = yn.toLowerCase();
if (yn.equals("yes") || yn.equals("yep")) {
stop = 0;
}
}
if (stop == 1) {
con = 0;
}
}
af.close();
}
}
as you can see, I tried myself to solve it and even put a comment on some of the code,
but when it runs to the method and comes back, it fails because the scanner thinks there is
something to scan before I wrote something. here is the exception-
Exception in thread "main" java.util.NoSuchElementException
at java.base/java.util.Scanner.throwFor(Scanner.java:937)
at java.base/java.util.Scanner.next(Scanner.java:1478)
at Main.main(Main.java:12)
You need a mechanism to loop-back (i.e. ask the user to enter the data again) in case of an invalid entry. One of the most common ways is to use do-while loop which guarantees to execute its body at least once. Check this tutorial to learn more about it.
Use Scanner::nextLine instead of Scanner::next, Scanner::nextInt etc. because they do not consume the newline character, created by hitting Enter key, from the input. Check this discussion to learn more about it.
Last but not least, never close a Scanner for System.in as it also closes System.in and there is no way to open it again without restarting the JVM. Note: If you are using Scanner to scan a File, make sure to close it in order to release the resource.
Demo:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int option;
boolean valid;
Scanner input2 = new Scanner(System.in);
do {
valid = true;
System.out.println("Choose an option:\n" + "1-Addition\n" + "2-Subtraction\n" + "3-Exit");
try {
option = Integer.parseInt(input2.nextLine());
if (option < 1 || option > 3) {
throw new IllegalArgumentException();
}
// ...Place here the rest of code (which is based on the value of option)
} catch (IllegalArgumentException e) {
System.out.println("This is an invalid entry. Please try again.");
valid = false;
}
} while (!valid);
}
}
A sample run:
Choose an option:
1-Addition
2-Subtraction
3-Exit
x
This is an invalid entry. Please try again.
Choose an option:
1-Addition
2-Subtraction
3-Exit
10.5
This is an invalid entry. Please try again.
Choose an option:
1-Addition
2-Subtraction
3-Exit
1
Did you remember to import java.util.Scanner?
Or how do you compile your source file?
I had that same error message when compiled with gradle and i was missing one tiny line in gradle build file.

What is the best way to read number from console using scanner?

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);
}

Validating multiple Inputs with Scanner

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);

Looping around a try catch

In the below code I am attempting to allow the program to catch an exception for an invalid input from user but still allow the program to loop back to the start of the method once exception has been caught. However in my example once there is an exception the program terminates. How can I rectify this? Thank a lot in advance!
public static void add() {
// Setting up random
Random random = new Random();
// Declaring Integers
int num1;
int num2;
int result;
int input;
input = 0;
// Declaring boolean for userAnswer (Defaulted to false)
boolean correctAnswer = false;
do {
// Create two random numbers between 1 and 100
num1 = random.nextInt(100);
num1++;
num2 = random.nextInt(100);
num2++;
// Displaying numbers for user and getting user input for answer
System.out.println("Adding numbers...");
System.out.printf("What is: %d + %d? Please enter answer below", num1, num2);
result = num1 + num2;
do {
try {
input = scanner.nextInt();
} catch (Exception ex) {
// Print error message
System.out.println("Sorry, invalid number entered for addition");
// flush scanner
scanner.next();
correctAnswer=false;
}
} while (correctAnswer);
// Line break for code clarity
System.out.println();
// if else statement to determine if answer is correct
if (result == input) {
System.out.println("Well done, you guessed corectly!");
correctAnswer = true;
} else {
System.out.println("Sorry incorrect, please guess again");
}
} while (!correctAnswer);
}// End of add
I'm not quite sure about the exceptions part, but have you maybe though about just using if statements?
Scanner has a method 'hasNextInt' which you can use to check that the the input is na int. For example:
Scanner scan = new Scanner(System.in);
int i=0;
boolean correctAnswer = false;
while(correctAnswer == false){
if(scan.hasNextInt()){
i = scan.nextInt(); correctAnswer = true;
}else{ System.out.println("Invalid entry");
correctAnswer = false;
scan.next();
}
System.out.println(i);
}
Sorry that it doesn't actually directly answer your question, but I though you might want to know about this possible way too. :)
Instead of throw an exception maybe you can use the method hasNextInt() which returns true if the token is a number.
But if you want absolutely use the try catch block, you have to remove the scanner.next() instrsctions because when nothings available on the buffer, it's throws an NoSuchElementException
I think solution i am giving can be improved but this is simple modification to fix your code: (just add new condition variable to check if further input/ans attempts required)
Hope it helps - MAK
public class StackTest {
private static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) throws InterruptedException{
// Setting up random
Random random = new Random();
// Declaring Integers
int num1;
int num2;
int result;
int input;
input = 0;
// Declaring boolean for userAnswer (Defaulted to false)
boolean correctAnswer = false;
//MAK: Add new condition for checking need of input
boolean needAnswer = true;
do {
// Create two random numbers between 1 and 100
num1 = random.nextInt(100);
num1++;
num2 = random.nextInt(100);
num2++;
// Displaying numbers for user and getting user input for answer
System.out.println("Adding numbers...");
System.out.printf("What is: %d + %d? Please enter answer below",
num1, num2);
result = num1 + num2;
while(needAnswer){
try {
input = scanner.nextInt();
needAnswer = false;
} catch (Exception ex) {
// Print error message
System.out.println("Sorry, invalid number entered for addition");
// flush scanner
scanner.next();
needAnswer = true;
}
} ;
// Line break for code clarity
System.out.println();
// if else statement to determine if answer is correct
if (result == input) {
System.out.println("Well done, you guessed corectly!");
correctAnswer = true;
} else {
System.out.println("Sorry incorrect, please guess again");
needAnswer = true;
}
} while (!correctAnswer);
}
}
If you want to have the following:
1) Ask the user how much is x + y
2) Let the user answer
3) If answer is invalid (e.g. user typed in "www"), let the user type his answer to question 1) again
than you should replace your inner do-while loop with the following:
boolean validInput = true;
do {
try {
input = scanner.nextInt();
} catch (Exception ex) {
// Print error message
System.out.println("Sorry, invalid number entered for addition. Please enter your answer again.");
// flush scanner
scanner.next();
validInput = false;
}
} while (!validInput);

Categories

Resources