I am working on creating a simple calculator program (first week into this java programming).
problem background: only 5 options are valid. (1-add; 2- subtract; 3- multiple;4. divide; and 5.exit). when users enter 1-4 options, results will populate but users need to loop back to reenter data till option 5 is selected. 5 is to exit the program(the only way to end the loop/program). my questions: 1. how to stop try-catch from running nonstop? is there a better way to implement try-catch? e.g., handling string data error messages.Ideally, if a string is entered, the code should loop back to restart again by producing the message "please reenter the number..." until a valid number is entered by users 2. I am trying to use as many static methods as possible in the main class. i am not sure whether the way I did was accurate?
Here is the code I input:
12 2
//-everything works well.
2 //-enter again
s s (string entry-error)
then, the below message populates:
"You have entered invalid floats. please re-enter:
Exception in thread "main" java.util.InputMismatchException
...
at calculator.performSubtract(calculator.java:65)
at calculator.main(calculator.java:34)"
code(sample)
public class calculator {
//use static methods to implement the program
static Scanner userInput = new Scanner(System.in);
static int userChoice;
static float numberOne;
static float numberTwo;
static float answer;
static int choice;
public static void main(String[] args) {
do {
//this menu statement has to be repeated unless 5 is entered (exit the
//program)
System.out.println("Welcome to <dj's> Handy Calculator\n\n\t \1. Addition \n\t 2. Subtraction\n\t 3. Multiplication\n\t 4. Division\n\t 5. Exit\n\n");
System.out.print("What would you like to do? ");
try {
choice = userInput.nextInt();
}catch (InputMismatchException e) {
continue;
}
switch (choice) {
case 2: performSubtract();
break;
...
case 5: exit();
break;
}
}while(choice >0 && choice <5);
userInput.close();
}
public static void performSubtract () {
//catch error statement.
try {
numberOne = userInput.nextFloat();
numberTwo= userInput.nextFloat();
answer= numberOne-numberTwo;
} catch (Exception e) {
System.out.println("You have entered invalid floats. please re-enter: ");
numberOne = userInput.nextFloat();
numberTwo= userInput.nextFloat();
}
System.out.printf("Please enter two floats to subtraction, separated by a space: %.1f %.1f\n", numberOne, numberTwo);
System.out.printf("Result of subtraction %.1f and %.1f is %.1f\n", numberOne, numberOne, answer);
System.out.println("\nPress enter key to continue...");
}
}
I believe the issue is that you are not clearing the problem token from the scanner.
Your catch statement prints an error message, and then goes around to try and parse the same token into an int or float again.
You might check here: https://www.geeksforgeeks.org/scanner-nextint-method-in-java-with-examples/
It looks like you need to call userInput.next() to advance past the invalid token.
Also, hasNextInt() will let you avoid the catch altogether if you prefer.
Your error lies in the fact that Scanner.nextFloat, when reading an invalid input, does not advance the current token. This means that when you call nextFloat twice again in the catch statement, you once again read the tokens s and s, the first of which will cause an InputMismatchException to be thrown once again. You should change your performSubtract method to look something like this:
public static void performSubtract () {
//catch errors
System.out.println("Please enter two floats to subtraction, separated by a space");
userInput.nextLine();//ignore the new line
do {
try {
String[] nextLineTokens = userInput.nextLine().split("\\s+");
if(nextLineTokens.length != 2)
{
System.out.println("You have not entered two floats. please re-enter:");
continue;
}
numberOne = Float.parseFloat(nextLineTokens[0]);
numberTwo = Float.parseFloat(nextLineTokens[1]);
answer= numberOne-numberTwo;
break;
}
catch (Exception e) {
System.out.println("You have entered invalid floats. please re-enter: ");
}
} while (true);
System.out.printf("You entered: %.1f %.1f\n", numberOne, numberTwo);
System.out.printf("Result of subtraction %.1f minus %.1f is %.1f\n", numberOne, numberTwo, answer);
System.out.println("\nPress enter key to continue...");
userInput.nextLine();
}
Additionally, your parsing code continues if you enter an invalid input, but exits if you type in a number that is not 1-5. If it is the first time that you read in input, the code exits for invalid inputs as well. You should probably change your parse iteration loop as so:
public static void main(String[] args) {
while(choice != 5) {
//this menu statement has to be repeated unless 5 is entered (exit the
//program)
System.out.println("Welcome to <dj's> Handy Calculator\n\n\t 1. Addition \n\t 2. Subtraction\n\t 3. Multiplication\n\t 4. Division\n\t 5. Exit\n\n");
System.out.print("What would you like to do? ");
try {
choice = userInput.nextInt();
}
catch (InputMismatchException e) {
userInput.next();
continue;
}
switch (choice) {
case 2: performSubtract();
break;
// ...
case 5: exit();
break;
}
}
userInput.close();
}
To the first question: try-catch block are usually used to see if your code are running through without error. By what you explain what you are trying to do, I would instead use a while-loop before the assignment for numberOne and numberTwo whether the input was float or not like:
// pseudo
while(input != float || input2 != float)
{
print(please reenter)
}
numberOne = input
numberTwo = input2
Related
I have created a 'car finance' calculator in Java however I want to make sure that not only the happy path is covered. When the user enters a string, the program quits because it's expecting an integer. Then I thought what if I set the input as a string and then convert it to an integer but I only want this conversion to happen IF the input is recognised as an integer... if that makes sense.
if(a.equalsIgnoreCase("Blue Car")) {
System.out.println("This car is £9,000");
Scanner input = new Scanner(System.in);
System.out.println("Please type in your deposit amount.");
String value = "";
int intValue;
value = input.nextLine();
try {
intValue = Integer.valueOf(value);
} catch (NumberFormatException e) {
System.out.println("Please print only numbers!");
}
if(value < 9000) {
System.out.println("The price of the car after your deposit is: " + (9000 - intValue));
System.out.println("Please confirm the left over price after your deposit by typing it in.");
int value1 = 0;
value1 = input.nextInt();
System.out.println("How long would you like the finance to be?");
System.out.println("12 Months, 24 Months, 36 Months, 48 Months");
System.out.println("Please type either 12, 24, 36 etc");
int value2 = 0;
value2 = input.nextInt();
System.out.println("You will be paying " + value1 / value2 + " pounds a month!"); }
else if(value.equalsIgnoreCase ("")){
System.out.println("Please only enter numbers.");
}
else {
System.out.println("Great - you can pay the car in full!");
chooseOption = true;
}
I tried using parseInt however I only want parseInt to happen if a number is entered.
I want my program to be able to recognise if the user input is an integer, then perform the if/else statement which does calculations with that integer and if the input is NOT an integer then I want a message to pop up saying 'Please make sure you enter numbers'.
UPDATE
I have added the method in which someone suggested in comments but I am unsure how to fit it in with the code I have as it's telling me still that value is not an integer and therefore I cannot use '<'.
From the docs of java.lang.Integer:
Throws:
NumberFormatException - if the string does not contain a parsable integer.
So simply catch that exception, and you know the String didn't contain a parsable integer.
int result;
try {
result = Integer.parseInt(value);
}
catch (NumberFormatException e) {
// value was not valid, handle here
}
Welcome to Stack Overflow.
You are on exactly the right path but you need to understand exceptions - when parseInt tries to Parse a value that isn't an integer it throws an exception. In Java we can catch and exception and deal with it (rather than letting it kill the run of the program).
For your case it looks like this:
try {
int result = Integer.parseInt(value);
//Do your normal stuff as result is valid
}
catch (NumberFormatException e)
{
// Show your message "Please only enter numbers"
}
//Code continues from here in either case
You could use StringUtils.isNumeric if you feel like adding a third party library.
If your use case is simple enough, I would probably do as follows:
int intValue;
String value = "";
value = input.nextLine();
try {
intValue = Integer.valueOf(value);
} catch (NumberFormatException e) {
System.out.println("Please print only numbers!");
}
I am making a very basic battleships game. Unlike the real thing, the program generates three random integers from 0 to 6. The player then has to guess where the ships are by inputting a integer.
So, the program as it is now:
public class digitBattleShips {
static int choice;
int playerScore;
int shipLoc1;
int shipLoc2;
int shipLoc3;
Random rand = new Random();
static Scanner input = new Scanner(System.in);
public void digitBattleShipsGame() {
shipLoc1 = rand.nextInt(7);
shipLoc2 = rand.nextInt(7);
shipLoc3 = rand.nextInt(7);
System.out.println(
"Welcome to digit BattleShips! In this game, you will choose a
number from 0 to 6. There are 3 ships to destroy, if you get them
all, you win");
while (playerScore != 3) {
System.out.println("Choose a number from 0 to 6");
playerChoice();
if (choice == shipLoc1 || choice == shipLoc2 || choice == shipLoc3) {
System.out.println("KABOOOOOOM!");
playerScore++;
} else {
System.out.println("Sploooosh...");
}
}
System.out.println("HURRRAAAAAAY you win");
}
public static void playerChoice() {
try {
choice = (int) input.nextInt();
while (choice<0 || choice>6) {
System.out.println("Error. You have to choose a number from 0 to 6");
playerChoice();
} }
catch (InputMismatchException ex) {
System.out.println("Invalid input! You have to enter a number");
playerChoice();
}
}
public static void main(String[] args) {
digitBattleShips digit = new digitBattleShips();
digit.digitBattleShipsGame();
}
}
At the moment, this is what happens:
1 ) If the player chooses an integer from 0 to 6 the while loop works as intended and will continue until the player hits the three ships represented by shipLoc1, shipLoc2 and shipLoc3
2 ) If the player chooses a number above or below 0 and 6, an error is shown, and the player gets prompted again for another input. Works as intended here.
3 ) If the player chooses a char, string, float number etc. then the exception is thrown BUT it does not allow the player to have another chance of changing their input.
I thought creating a method specifically designed (named playerChoice() as in the code) to allow input would sort this out and hence, after the exception is thrown, this method activates again so the player can choose another number. However, from my limited understanding, it does look like that the invalid choice is stored and hence, when this method is called, the exception is automatically thrown again as the invalid choice stays throughout. This then creates an infinite loop of the exception being thrown.
The idea is to allow another input if the one before it is invalid i.e. not an integer so that 3) operates in the same manner as 2)
I think the confusion I am facing here may be due to how I placed the while and try / catch techniques. Please provide some direction and how to prevent 3) from happening
This is what I would do:
public static void playerChoice()
{
try
{
String inStr = input.nextLine();
int inInt = Integer.parseInt(inStr); // throws exception.
if (inInt < 0 || inInt > 6) // If number out of range, try again.
{
System.out.println("Error. You have to choose a number from 0 to 6");
playerChoice();
}
else
{
choice = inInt;
}
}
catch (NumberFormatException ex) // If exception, try again.
{
System.out.println("Invalid input! You have to enter a number");
playerChoice();
}
}
Instead of relying on Scanner.nextInt(), I would read the input as String first (since no parsing is involved at this step), then use Integer.parseInt() to parse manually. It is usually a good practice to seperate reading/fetching from casting/parsing.
After a little bit of googling it looks like input isn't cleared after the exception is thrown (see How does input.nextInt() work exactly?).
As a result, because you aren't calling "input.next();", it keeps reading the same input, realizing it isn't an integer and throwing the exception.
Solution:
try {
choice = (int) input.nextInt();
while (choice<0 || choice>6) {
System.out.println("Error. You have to choose a number from 0 to 6");
playerChoice();
} }
catch (InputMismatchException ex) {
System.out.println("Invalid input! You have to enter a number");
input.next();
playerChoice();
}
For a college assessment I'm having to use a Scanner called sc with a class-level scope, and the entirety of the program has to be contained in a single class. The main method calls a menu() method, which uses the Scanner and a for loop to call one of two methods in response to user input.
One of the two methods uses the Scanner to calculate the factorial of an input integer. Once the method is executed, the for loop in menu() continues. To avoid an InputMismatchException due to the user entering a float, I used try/catch. However when the program returns back to the menu() for loop the Scanner causes an InputMismatchException when assigning to choice. How can I get Scanner to prompt the user for input again? Apologies if I'm missing something obvious, this is the first programming language I've ever learned. This should be the stripped down compilable code:
package summativeassessment;
import java.util.InputMismatchException;
import java.util.Scanner;
public class SummativeAssessment {
private static Scanner sc = new Scanner(System.in);
public static void main(String[] args) {
menu();
}
public static void menu(){
String fName;
String sName;
System.out.print("Enter your first name: ");
fName = sc.next();
System.out.print("Enter your last name: ");
sName = sc.next();
try{
for(int choice = 1; choice!=0;){
System.out.print("Option 1 to generate username. Option 2 to calculate factorial. Press 0 to quit: ");
choice = sc.nextInt();
switch(choice){
case 2:
System.out.println(fName+" "+sName+", you have selected option 2");
numberFactorial();
break;
case 0:
break;
default:
System.out.println("Invalid option. Please try again.");
}
}
} catch(InputMismatchException ex){
String msg = ex.getMessage();
System.out.println(msg);
}
}
public static void numberFactorial(){
System.out.print("Enter a number: ");
try{
int numIn = sc.nextInt();
long result = numIn;
if(numIn>0){
for(int factor = 1; factor<numIn; factor++){
result *= factor;
if(factor==numIn-1){
System.out.println("The factorial is "+result);
}
}
}
else{
System.out.println("Enter a positive integer greater than 0");
}
}
catch(InputMismatchException ex){
System.out.println("Input invalid");
}
}
}
I debugged your code and got this result:
If you enter a float as input you trigger the InputMismatchException but there is still something in your buffer. So the next time sc.nextInt() is called, it won't wait until you input a value because something is in the buffer already, so it takes the next value out of the buffer and tries to interpret is as an integer. However, it fails to do so, because it is not an integer, so an InputMismatchException is raised again and caught in your menu's catch, now leading to the exit of the program.
The solution is to draw whatever is left in the buffer after the exception was raised the first time.
So the working code will contain a buffer clearing sc.next() inside the exception:
public static void numberFactorial(){
System.out.print("Enter a number: ");
try{
int numIn = sc.nextInt();
long result = numIn;
if(numIn>0){
for(int factor = 1; factor<numIn; factor++){
result *= factor;
if(factor==numIn-1){
System.out.println("The factorial is "+result);
}
}
}
else{
System.out.println("Enter a positive integer greater than 0");
}
}
catch(InputMismatchException ex){
System.out.println("Input invalid");
sc.next();
}
}
While using the nextInt() method of Scanner class, if InputMismatchException is being thrown, shall I handle that by catch block ?
It's a runtime exception, but caused by user input and not programmer's mistake.
Here is my code.
package com.sample.programs;
import java.util.InputMismatchException;
import java.util.Scanner;
public class ScannerPractice {
public static void main(String[] args) {
readInteger();
}
private static void readInteger() {
// Created a Scanner object
Scanner input = new Scanner(System.in);
// Display a prompt text
System.out.println("Please enter an integer");
// Accept the input from user
int number;
try {
number = input.nextInt();
// Display the output to user
System.out.println("You entered: " + number);
} catch (InputMismatchException exception) {
System.err.println("You have entered wrong input. Please enter a number");
// Log the stack trace
readInteger();
} finally {
input.close();
}
}
}
Yes. Is better to handle the user wrong input beacouse you cannot control or be sure that the user will aligned data correctly, and you cannot read doubles, or strings with readInteger().
So I will handle the exception.
Regards.
No, you should call hasNextInt() before calling nextInt().
The exception truly means programmer error, since the programmer forgot to check validity before calling the method.
If you then want to prompt the user again, remember to discard the bad input first.
Scanner input = new Scanner(System.in);
int value;
for (;;) {
System.out.println("Enter number between 1 and 10:");
if (! input.hasNextInt()) {
System.out.println("** Not a number");
input.nextLine(); // discard bad input
continue; // prompt again
}
value = input.nextInt();
if (value < 1 || value > 10) {
System.out.println("** Number must be between 1 and 10");
input.nextLine(); // discard any bad input following number
continue; // prompt again
}
if (! input.nextLine().trim().isEmpty()) {
System.out.println("** Bad input found after number");
continue; // prompt again
}
break; // we got good value
}
// use value here
// don't close input
I have the following code, where the idea is that the user will input two numbers and the sum of the two will be calculated.
If an invalid value, e.g. a character is entered, an error message should be outputted but I keep getting errors
Java
package calculator;
import java.util.Scanner;
public class calculator {
/**
* #param args
*/
public static void main(String[] args) {
double n1, n2;
String operation;
Scanner scannerObject = new Scanner(System.in);
System.out.println("Enter first number");
n1 = scannerObject. nextDouble();
System.out.println("Enter second number");
n2 = scannerObject. nextDouble();
Scanner op = new Scanner(System.in);
System.out.println("Enter your operation");
operation = op.next();
switch (operation) {
case "+":
System.out.println("Your answer is " + (n1 + n2));
break;
case "-":
System.out.println("Your answer is " + (n1 - n2));
break;
case "/":
System.out.println("Your answer is " + (n1 / n2));
break;
case "*":
System.out.println("Your asnwer is " + (n1 * n2));
break;
default:
System.out.println("I do not know!");}
}
int function(){
Scanner input = new Scanner(System.in);
System.out.print("Enter an integer between 1-100: ");
int range;
while(true){
if(input.hasNextInt()){
range = input.nextInt();
if(0<=range && range <= 100)
break;
else
continue;
}
input.nextLine(); //Comsume the garbage value
System.out.println("Enter an integer between 1-100:");
}
return range;
}
}
and these are the error messages I get:
Errors
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 calculator.calculator.main(calculator.java:14)
I've tried so many different things but can't get it to work as I want it.
Can anyone be of any assistance here?
Thanks for reading
This exception is thrown by an instance of the Scanner class to indicate that a retrieved token does not match the pattern for the expected type, or that the retrieved token is out of range.
You can see the documentation for the exception here: https://docs.oracle.com/javase/7/docs/api/java/util/InputMismatchException.html
Taken from documention on Scanner
double nextDouble()
Returns the next token as a long. If the next token is not a float or
is out of range, InputMismatchException is thrown.
I suspect that your not inputting your number correctly. Ensure that your input is of the correct format.
You should also set the locale of your scanner as some locales expect a comma , instead of a dot ., such as:
Scanner scanner = new Scanner(System.in).useLocale(Locale.US);
Your first two inputs should be numbers. If this is true, then it's probably the decimal mark for your numbers. You need a dot(.) not a comma (,)
It seems that you are not entering any integer as input.
You can solve this by handling the exception this way :
try {
if(input.hasNextInt()){
range = input.nextInt();
if(0<=range && range <= 100)
break;
else
continue;
}
input.nextLine();
}
catch (InputMismatchException e) {
input.nextLine();
}
Your issue is at,
scannerObject. nextDouble();
You are trying to get a double but entering a string. You will need to do some sort of a input validation like below to stop program from crashing incase of invalid inputs.
try {
System.out.println("Enter first number");
n1 = scannerObject. nextDouble();
}
catch(InputMismatchException inEx) {
System.out.println("Invalid input");
}
Then you may want to create a loop to get the input again and agin until valid input is detected.
Edit
You'll need to,
import java.util.InputMismatchException;
Also create a loop to get a valid input from a user. Something like below. This is just an example, you'll need to do something like this to work with your code. Also need to make sure n1 and n2 are initiated before you actually use their values.
boolean notValidInput = true;
while(notValidInput) {
try {
System.out.println("Enter first number");
n1 = scannerObject. nextDouble();
notValidInput = false;
}
catch(InputMismatchException inEx) {
System.out.println("Invalid input. Please try again!");
}
}