When the program is run, the catch is not catching an error when a negative number is entered or a letter. The program runs fine otherwise and there are no errors with anything else. It is just the catch not catching when an incorrect input is entered.
for (int customer=0; customer<numberOfCustomers; customer++) {
try {
// get amount used by customer as String, convert to double
GBused = Double.valueOf(Accounts[customer][USED]);
// compute bill based on the customer's plan selection
switch (Accounts[customer][SELECTION]) {
case "Plan-A":
bill = computeBill (GBused, PLAN[A][LIMIT], PLAN[A][PRICE]);
break;
case "Plan-B":
bill = computeBill (GBused, PLAN[B][LIMIT], PLAN[B][PRICE]);
break;
case "Plan-C":
bill = computeBill (GBused, PLAN[C][LIMIT], PLAN[C][PRICE]);
break;
case "Plan-D":
bill = computeBill (GBused, PLAN[D][LIMIT], PLAN[D][PRICE]);
break;
default:
bill = 0.00;
break;
}
// convert the bill to a String and save into the array
Accounts[customer][BILL] = String.valueOf(bill);
} // end of try
catch (NumberFormatException e) {
System.out.println ("Values for GB used must be numeric");
}
There is no exception being thrown. You need to check for valid values at the input. For characters, there is type casting and the ASCII value of the character is used.
Try using "(Exception e)" to catch any possible exception you may get.
Related
Good morning everyone... I am wondering where to put the try-catch block for not integer Input(InputMismatchException) to work in this code,
If I put it here doesn't work, if I put it before while, it's an infinite loop, if you can explain where and why it will be perfect, thank you for your time.
public void additionalIngredients() {
Set<Integer> set = new HashSet<>();
boolean flag = false;
while (!flag) {
System.out.println("Enter your choice for extra toppings ");
int choices = scanner.nextInt();
scanner.nextLine();
try {
switch (choices) {
case 0:
System.out.println("Done");
flag = true;
break;
case 1:
if (!set.contains(choices)) {
double extraSauce = 1.2;
setAdditionalStuff(getAdditionalStuff() + extraSauce);
System.out.println("Extra sauce added on your pizza \n");
break;
} else {
System.out.println("You already added extra sauce, please consider to add something else");
break;
}
case 2:
if (!set.contains(choices)) {
double extraCheese = 2.3;
setAdditionalStuff(getAdditionalStuff() + extraCheese);
System.out.println("Extra cheese added on your pizza \n");
break;
} else {
System.out.println("You already added extra cheese, please consider to add something else");
break;
}
case 3:
if (!set.contains(choices)) {
double largeDough = 0.7;
setAdditionalStuff(getAdditionalStuff() + largeDough);
System.out.println("Your pizza has a large Dough \n");
break;
} else {
System.out.println("Your pizza has already a large dough, consider something else");
break;
}
}
set.add(choices);
} catch (InputMismatchException e) {
System.out.println("Please enter an integer!");
}
}
}
There are may ways to go about this. Always strive for solutions that make your code easier to read and understand.
One way to do that: you could for example create another helper method fetchSelectionFromUser() that does one thing only: loop (with try catch) until the user entered a valid number.
One guiding rule is the single layer of abstraction principle. And that tells you that having a-switch-in-a-try-in-a-loop isn't the way to go. As said, you could go for a loop that simply calls two methods: one that fetches the input, and another one that processes it.
I am new to Java and I tried to use exceptions in my Java code to give the user an alert if in case he/she types a negative number or a non-numerical value in the text field. But still, when I enter a single-digit positive number, the catch blocks get executed.
//textfield to enter the amount of Rs.
txt_rupees = new JTextField();
//KeyListener to check if the content entered in the text field is a number or not.
txt_rupees.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
try {
//convert the user input in the textfield from string to double
double check = Double.parseDouble(txt_rupees.getText());
//checking if the number entered by the user is positive or not.
if (check > 0) {
lb_check1.setText(" ");
}
else {
lb_check1.setText("Please enter a valid number");
}
}
catch (NumberFormatException ne){
//If the user enters a non-numerical character then this message should be displayed by the label.
lb_check1.setText("ALERT: Please enter a valid float or int value in the textfield");
}
}
});
To understand how try-catch block work, I will give an example.
class InsufficientMoneyException extends Exception{
InsufficientMoneyException(int money){
System.out.println("You only have $"+money);
}
}
class A throws InsufficientMoneyException{
try{
int money = 100;
if(money<1000) throw new InsufficientMoneyException(money);
System.out.println("I am NOT being executed!");
} catch (InsufficientMoneyException e){System.out.println("I am being executed!");}
}
Code block will get executed unless it encounters a statement that tells it to throw a exception. After throwing the exception, the catch will catch the exception and the catch block will get executed.
In your case,
double check = Double.parseDouble(txt_rupees.getText());
The library function parseDouble() will throw the NumberFormatException so the lines in try block after this line, won't get executed.
I'm looking for an exception on how to catch an invalid String that is user input. I have the following code for a exception on an integer input:
try {
price = Integer.parseInt(priceField.getText());
}
catch (NumberFormatException exception) {
System.out.println("price error");
priceField.setText("");
break;
But I'm not aware of a specific exception for strings, the input is a simple JTextBox so the only incorrect input I can think of is if the user enters nothing into the box, which is what I'm looking to catch.
if (textField.getText().isEmpty())
is all you need.
Or maybe
if (textField.getText().trim().isEmpty())
if you also want to test for blank inputs, containing only white spaces/tabs.
You generally don't use exceptions to test values. Testing if a string represents an integer is an exception to the rule, because there is no available isInt() method in String.
You can do like
if (priceField.getText().isEmpty())
throw new Exception("priceField is not entered.");
You could check if priceField contains a string by using this:
JTextField priceField;
int price;
try {
// Check whether priceField.getText()'s length equals 0
if(priceField.getText().getLength()==0) {
throw new Exception();
}
// If not, check if it is a number and if so set price
price = Integer.parseInt(priceField.getText());
} catch(Exception e) {
// Either priceField's value's length equals 0 or
// priceField's value is not a number
// Output error, reset priceField and break the code
System.err.println("Price error, is the field a number and not empty?");
priceField.setText("");
break;
}
When the if-statement is true (If the length of priceField.getText() is 0) an exception gets thrown, which will trigger the catch-block, give an error, reset priceField and break the code.
If the if-statement is false though (If the length of priceField.getText() is greater or lower than 0) it will check if priceField.getText() is a number and if so it sets price to that value. If it not a number, a NumberFormatException gets thrown, which will trigger the catch-block etc.
Let me know if it works.
Happy coding :) -Charlie
if you want your exception to be thrown during the normal operation of the Java Virtual Machine, then you can use this
if (priceField.getText().isEmpty())
throw new RunTimeException("priceField is not entered.");
I have a method that a wrote. This method just scans for a user entered integer input. If the user enters a character value it will throw an input mismatch exception, which is handled in my Try-Catch statement. The problem is that, if the user inputs anything that is not a number, and then an exception is thrown, I need the method to loop back around to ask the user for input again. To my understanding, a Try catch statement automatically loops back to the Try block if an error is caught. Is this not correct? Please advise.
Here is my method (it's pretty simple):
public static int getMask() {
//Prompt user to enter integer mask
Scanner keyboard = new Scanner(System.in);
int output = 0;
try{
System.out.print("Enter the encryption mask: ");
output = keyboard.nextInt();
}
catch(Exception e){
System.out.println("Please enter a number, mask must be numeric");
}
return output;
}//end of getMask method
Here is how the method is implemented into my program:
//get integer mask from user input
int mask = getMask();
System.out.println("TEMP mask Value is: " + mask);
/***********************************/
Here is my updated code. It creates an infinate loop that I can't escape. I don't understand why I am struggling with this so much. Please help.
public static int getMask() {
//Prompt user to enter integer mask
Scanner keyboard = new Scanner(System.in);
int output = 0;
boolean validInput = true;
do{
try {
System.out.print("Enter the encryption mask: ");
output = keyboard.nextInt();
validInput = true;
}
catch(InputMismatchException e){
System.out.println("Please enter a number, mask must be numeric");
validInput = false;
}
}while(!(validInput));
return output;
/********************/FINAL_ANSWER
I was able to get it finally. I think I just need to study boolean logic more. Sometimes it makes my head spin. Implementing the loop with an integer test worked fine. My own user error I suppose. Here is my final code working correctly with better exception handling. Let me know in the comments if you have any criticisms.
//get integer mask from user input
int repeat = 1;
int mask = 0;
do{
try{
mask = getMask();
repeat = 1;
}
catch(InputMismatchException e){
repeat = 0;
}
}while(repeat==0);
To my understanding, a Try catch statement automatically loops back to the Try block if an error is caught. Is this not correct?
No this is not correct, and I'm curious as to how you arrived at that understanding.
You have a few options. For example (this will not work as-is but let's talk about error handling first, then read below):
// Code for illustrative purposes but see comments on nextInt() below; this
// is not a working example as-is.
int output = 0;
while (true) {
try{
System.out.print("Enter the encryption mask: ");
output = keyboard.nextInt();
break;
}
catch(Exception e){
System.out.println("Please enter a number, mask must be numeric");
}
}
Among others; your choice of option usually depends on your preferred tastes (e.g. fge's answer is the same idea but slightly different), but in most cases is a direct reflection of what you are trying to do: "Keep asking until the user enters a valid number."
Note also, like fge mentioned, you should generally catch the tightest exception possible that you are prepared to handle. nextInt() throws a few different exceptions but your interest is specifically in an InputMismatchException. You are not prepared to handle, e.g., an IllegalStateException -- not to mention that it will make debugging/testing difficult if unexpected exceptions are thrown but your program pretends they are simply related to invalid input (and thus never notifies you that a different problem occurred).
Now, that said, Scanner.nextInt() has another issue here, where the token is left on the stream if it cannot be parsed as an integer. This will leave you stuck in a loop if you don't take that token off the stream. To that end you actually want to use either next() or nextLine(), so that the token is always consumed no matter what; then you can parse with Integer.parseInt(), e.g.:
int output = 0;
while (true) {
try{
System.out.print("Enter the encryption mask: ");
String response = keyboard.next(); // or nextLine(), depending on requirements
output = Integer.parseInt(response);
break;
}
catch(NumberFormatException e){ // <- note specific exception type
System.out.println("Please enter a number, mask must be numeric");
}
}
Note that this still directly reflects what you want to do: "Keep asking until the user enters a valid number, but consume the input no matter what they enter."
To my understanding, a Try catch statement automatically loops back to the Try block if an error is caught. Is this not correct?
It is indeed not correct. A try block will be executed only once.
You can use this to "work around" it (although JasonC's answer is more solid -- go with that):
boolean validInput = false;
while (!validInput) {
try {
System.out.print("Enter the encryption mask: ");
output = keyboard.nextInt();
validInput = true;
}
catch(Exception e) {
keyboard.nextLine(); // swallow token!
System.out.println("Please enter a number, mask must be numeric");
}
}
return output;
Further note: you should NOT be catching Exception but a more specific exception class.
As stated in the comments, try-catch -blocks don't loop. Use a for or while if you want looping.
The following code is in a while loop which then houses a switch as such:
System.out.println("Enter in a selection.");
System.out.println("Enter \"1\" for a default selection of die");
System.out.println("Enter \"2\" for a custom number of sides.");
//try the input to see if its an integer
try {
selection = sc.nextInt();
} catch (NumberFormatException e){
System.out.print("Your selection can only be an integer!");
}
switch (selection){
case1:
...
break;
case2:
...
break;
default:
...
//yell at them
continue;
}
I already have a default selection in the switch so that if a user enters in an invalid number like 4 (since there are only 2 cases) that it brings them back to the beginning of the loop. So, the issue is handling the exception. The exception does not get handled with the following above code and I don't know why. The try is housing the offending code.
As always, please ask for clarification if needed. Thanks.
The reason exception is not handled when you enter 4 is that 4 is a valid integer and nextInt() will not raise NumberFormatException exception.
You'd better enclose the switch in the try block.
Personally, I would put your input (and the try/catch block that goes with it) in its own, separate method. Return a boolean (true = valid integer) or a value that's out of range (perhaps "-1", depending on your program).
IMHO...
Scanner#nextInt() doesn't throw NumberFormatException
Scans the next token of the input as an int. An invocation of this method of the form nextInt() behaves in exactly the same way as the invocation nextInt(radix) , where radix< is the default radix of this scanner.
return the int scanned from the input
throws InputMismatchException
if the next token does not match the <i>Integer</i>
regular expression, or is out of range
throws NoSuchElementException if input is exhausted
throws IllegalStateException if this scanner is closed
Your exception handling seems right, with only issue that you are catching wrong exception. Please catch InputMismatchException and other two.
e.g. below:
try {
selection = sc.nextInt();
} catch (InputMismatchException e){
System.out.print("Your selection can only be an integer!");
}
Also you may want to put the above code in a while loop as below:
boolean validInput = false;
while(!validInput){
try {
selection = sc.nextInt();
validInput = true;
} catch (InputMismatchException e){
System.out.print("Your selection can only be an integer!");
}
}
This will repeatedly ask for input until a number is entered.
You should continue on the exception as there is no point in going ahead do the switch on the selection if the exception occurred.
} catch (InputMismatchException e){
System.out.print("Your selection can only be an integer!");
sc.nextLine();
continue;
}
The way you have it right now, if the exception were to occur you would be switching the old stale value held by selection.
But the main problem in your code is that the nextInt() method doesn't throw the NumberFormatException, instead it throws the InputMismatchException.
So you are trying to catch the wrong exception.
In the case of a Scanner, you can use the hasNextInt() method (and equivalents for other data types) rather than crashing and burning via exception:
while (some_condition) {
System.out.println("Enter in a selection.");
System.out.println("Enter \"1\" for a default selection of die");
System.out.println("Enter \"2\" for a custom number of sides.");
//try the input to see if its an integer
if (!sc.hasNextInt()) {
System.out.println("You must enter an integer!");
continue;
}
selection = sc.nextInt();
switch (selection){
case 1:
...
break;
case 2:
...
break;
default:
...
//yell at them
continue;
}
}
As Bhesh Gurung said, if you're in a loop, you should just use continue to go back to the beginning, like you do in the default case.
If you want to really handle the exception in the 'switch' statement, you need to expand the scope of the try-catch block:
System.out.println("Enter in a selection.");
System.out.println("Enter \"1\" for a default selection of die");
System.out.println("Enter \"2\" for a custom number of sides.");
//try the input to see if its an integer
try {
selection = sc.nextInt();
switch (selection){
case1:
...
break;
case2:
...
break;
default:
...
//yell at them
throw new NumberFormatException("Yelling message");
continue;
}
} catch (NumberFormatException e){
System.out.print("Your selection can only be an integer!");
}