I am having a little bit of a problem here. I am trying to figure out how to catch the IllegalArgumentException. For my program, if the user enters a negative integer, the program should catch the IllegalArgumentException and ask the user if he/she wants to try again. But when the exception is thrown, it doesn't give that option. It just terminates. I tried to use the try and catch method but it doesn't work for me. How do I catch this particular exception to continue to run instead of terminating?
public static void main(String[] args) throws IllegalArgumentException
{
String keepGoing = "y";
Scanner scan = new Scanner(System.in);
while(keepGoing.equals("y") || keepGoing.equals("Y"))
{
System.out.println("Enter an integer: ");
int val = scan.nextInt();
if (val < 0)
{
throw new IllegalArgumentException
("value must be non-negative");
}
System.out.println("Factorial (" + val + ") = "+ MathUtils.factorial(val));
System.out.println("Another factorial? (y/n)");
keepGoing = scan.next();
}
}
}
and
public class MathUtils
{
public static int factorial(int n)
{
int fac = 1;
for(int i = n; i > 0; i--)
{
fac *= i;
}
return fac;
}
}
You need to add the try catch block inside the loop to continue the working for the loop. Once it hits the illegal argument exception catch it in catch block and ask if the user wants to continue
import java.util.Scanner;
public class Test {
public static void main(String[] args)
{
String keepGoing = "y";
populate(keepGoing);
}
static void populate( String keepGoing){
Scanner scan = new Scanner(System.in);
while(keepGoing.equalsIgnoreCase("y")){
try{
System.out.println("Enter an integer: ");
int val = scan.nextInt();
if (val < 0)
{
throw new IllegalArgumentException
("value must be non-negative");
}
System.out.println("Factorial (" + val + ") = "+ MathUtils.factorial(val));
System.out.println("Another factorial? (y/n)");
keepGoing = scan.next();
}
catch(IllegalArgumentException i){
System.out.println("Negative encouneterd. Want to Continue");
keepGoing = scan.next();
if(keepGoing.equalsIgnoreCase("Y")){
populate(keepGoing);
}
}
}
}
}
Hope this helps.
Happy Learning :)
I don't think you want your main() method to be throwing an exception. Typically, this is the kind of thing that you'd put in try and catch blocks.
Honestly though, for this sort of thing an if/else would work better. (Unless you're just doing this as a toy example, to learn exceptions.)
Make another method called getNumber() that throws the IllegalArgumentException, that returns an int. Then put it inside the try/catch in the main().
public static void main(String[] args)
{
String keepGoing = "y";
Scanner scan = new Scanner(System.in);
while(keepGoing.equals("y") || keepGoing.equals("Y"))
{
int val = 0;
boolean flag=true;
while(flag){
try{
System.out.println("Enter an integer: ");
val = scan.nextInt();
if (val < 0)
{
throw new IllegalArgumentException
("value must be non-negative");
}
flag = false;
} catch(IllegalArgumentException e){
System.out.println("value must be non-negative");
}
}
System.out.println("Factorial (" + val + ") = "+ MathUtils.factorial(val));
System.out.println("Another factorial? (y/n)");
keepGoing = scan.next();
}
}
}
I would suggest you add a test on the negative value and display your message on the spot, then use an else block. Also, you could use String.equalsIgnoreCase() in your loop test like
String keepGoing = "y";
Scanner scan = new Scanner(System.in);
while (keepGoing.equalsIgnoreCase("y")) {
System.out.println("Enter an integer: ");
int val = scan.nextInt();
if (val < 0) {
System.out.println("value must be non-negative");
} else { // <-- skip negative value
System.out.println("Factorial (" + val + ") = "
+ MathUtils.factorial(val));
}
System.out.println("Another factorial? (y/n)");
keepGoing = scan.next();
}
Also, an int factorial(int) method can only the first 12 correct values. You could use a long or a BigInteger like
public static BigInteger factorial(int n) {
BigInteger fac = BigInteger.ONE;
for (int i = n; i > 1; i--) {
fac = fac.multiply(BigInteger.valueOf(i));
}
return fac;
}
Similar to some other answers, I would say that your main() method should not throw an exception to display an error message to the user, because that is not the purpose of exception handling mechanisms in Java. Exception handling is designed to enable methods to signal that something happened that should not have happened, so the methods that call those methods will know that they need to deal with them. In general, exceptions are caught, not thrown, by main() methods and other user interface methods.
I would make the method factorial() throw the IllegalArgumentException, rather than your main() method in your program class. Your main() method should use try and catch to handle this exception. With this design, if someone else wanted to use your MathUtils class, they would know that your factorial() method throws an IllegalArgumentException (especially if you document your code with javadoc), and would write their code to handle the exception. In the current situation, if someone tries to call MathUtils.factorial(-1), the return value would be 1 because the for loop inside factorial() would not execute at all (because i is initially set to -1, which is not greater than 0).
This is how I would revise your code:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String keepGoing = "y";
while(keepGoing.equalsIgnoreCase("y")) {
try { // This code might throw an exception
System.out.println("Enter an integer: ");
int val = scan.nextInt();
System.out.println("Factorial (" + val + ") = "+ MathUtils.factorial(val));
System.out.println("Another factorial? (y/n)");
keepGoing = scan.next();
} catch (IllegalArgumentException | InputMismatchException e) {
/* An InputMismatchException is thrown if the input is not an integer.
See the documentation for Scanner method nextInt() for more details.
*/
System.out.println("You must enter a non-negative integer.");
System.out.println("Try again? (y/n)");
keepGoing = scan.next();
}
}
}
}
and
public class MathUtils throws IllegalArgumentException {
public static int factorial(int n) {
if (fac < 0) {
throw new IllegalArgumentException("value must be non-negative");
}
int fac = 1;
for(int i = n; i > 0; i--) {
fac *= i;
}
return fac;
}
}
Related
I'm trying to make it to were is will throw my exception if the input is not a number and i cant figure it out, Could someone help me get on the right track
import java.util.Scanner;
class calculations
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
int number;
int total = 0;
try
{
} catch ( IllegalArgumentException e)
{
//error
}
while (true)
{
number = scan.nextInt();
if (number == 0)
{
break;
}
total += number;
}
System.out.println("Total is " + total);
}
}
You should use hasNextInt, which will allow you to check if the next token in the stream can be parsed as an int.
if (! scanner.hasNextInt()) throw new IllegalArgumentException()
I'm trying to make a method that gets the user's input of 6 numbers and add them to a Tree set of integers. I'm trying to make a try and catch exception so if the users accidentally enters in a letter it'll catch the exception and ask them to enter in a number. Right now the program crashes when you try to enter in a letter. It'll print out "Invalid" then crashes. I'm not sure whats going on. Can anyone provide some insight?
public static Set<Integer> getTicket()
{
int userInput;
TreeSet<Integer> getNumbers = new TreeSet<Integer>();
Scanner input = new Scanner(System.in);
System.out.println("Enter your 6 numbers between 1-40: ");
for (int i = 0; i<6 ; i++)
{
try
{
System.out.print(i+1 + ": ");
userInput = input.nextInt();
}
catch (InputMismatchException e)
{
System.out.println("Invalid");
userInput = input.nextInt();
}
getNumbers.add(userInput);
}
System.out.println("Your ticket was: " + getNumbers);
return getNumbers;
}
Just a few notes on some of the changes made. From your original code, one thing I noticed that is not really an error but a head scratcher. Both of your methods (getWinning Numbers() and getTicket() ) returned a Set<integer> set, however you did not use it in main. So I simply took the output from the methods and placed them in the main method, where they should be IMHO. Methods like these should do ONE thing and in this case is return a set of integers. No printing or anything else that’s all it does.
I changed the logic in the getTicket() method. I simply set up a loop that continued until you had 6 valid numbers. Inside that loop I use a try statement to weed out the invalid input. The way the try statement is set up is one of many ways that you could accomplish this. As you can see the statement immediately after the try (guess = Integer.parseInt(userInput);) is where the invalid input problem could pop up and throw a NumberFormatException. If the input is invalid, you drop immediately to the catch where we output a message and continue. If the input is valid then we simply check for duplicates and the range of the number. If the numbers are ok then add it to pickedNumbers and increment numberCount.
public class Lottery
{
public static Set<Integer> generateWinningNumbers()
{
Random rndNumbers = new Random();
TreeSet<Integer> winningNumbers = new TreeSet<Integer>();
int max = 40;
int min = 1;
int range;
int sixNum;
for (int i = 0; i < 6; i++)
{
range = max - min + 1;
sixNum = rndNumbers.nextInt(range) + min;
while (winningNumbers.contains(sixNum))
{
sixNum = rndNumbers.nextInt(range) + min;
}
winningNumbers.add(sixNum);
}
return winningNumbers;
}
public static Set<Integer> getTicket(Scanner input)
{
String userInput;
int guess;
TreeSet<Integer> pickedNumbers = new TreeSet<Integer>();
System.out.println("Enter your 6 numbers between 1-40: ");
int numberCount = 1;
while(numberCount < 7)
{
System.out.print(numberCount + ": ");
userInput = input.nextLine();
try
{
guess = Integer.parseInt(userInput);
if( guess > 0 && guess < 41 && (!pickedNumbers.contains(guess)) )
{
pickedNumbers.add(guess);
numberCount++;
}
else
{
if (pickedNumbers.contains(guess))
{
System.out.println("Number already picked: " + guess);
}
else
{
System.out.println("Invalid number. Pick a number between 1-40: " + guess);
}
}
}
catch (NumberFormatException e)
{
// bad input
System.out.println("Invalid input: " + userInput);
}
}
return pickedNumbers;
}
}
Changes in the Main now take advantage of the methods returning a Set of integers for us. We create two Set<Integer> variables (winningTicket and userTicket) then we simply get the returned sets from the methods and output the results as opposed to printing the results from the methods.
public static void main(String[] args) throws IOException
{
Scanner userInput = new Scanner(System.in);
boolean done = false;
String yesNo;
Set<Integer> winningTicket;
Set<Integer> userTicket;
while(!done)
{
winningTicket = Lottery.generateWinningNumbers();
userTicket = Lottery.getTicket(userInput);
System.out.println("Your ticket was: " + userTicket);
System.out.println("Winning Numbers: " + winningTicket);
System.out.print("\nWould you like to try again? ");
yesNo = userInput.nextLine();
if(!yesNo.equalsIgnoreCase("y"))
{
System.out.println("Done");
done = true;
}
}
userInput.close();
}
Hope this helps
This happens because you don't catch exceptions inside cath block. for loop doesn't look good here, try while:
public static Set<Integer> getTicket()
{
int userInput;
TreeSet<Integer> getNumbers = new TreeSet<Integer>();
Scanner input = new Scanner(System.in);
System.out.println("Enter your 6 numbers between 1-40: ");
int correct = 0;
while(correct < 6)
{
try
{
System.out.print((correct+1) + ": ");
userInput = input.nextInt();
getNumbers.add(userInput);
correct++;
}
catch (InputMismatchException e)
{
System.out.println("Invalid input");
}
}
System.out.println("Your ticket was: " + getNumbers);
return getNumbers;
}
Also you cant't print collection that simple:
System.out.println("Your ticket was: " + getNumbers);
What you can do, is to use streams:
System.out.println("Your ticket was: " + getNumbers.stream().map(Object::toString).collect(Collectors.joining(" ")));
I a making a program that will ask an int input from user and check whether user input is an integer or not. If no the program asks for an input tile it gets a integer.
Scanner in = new Scanner(System.in);
System.out.println("Eneter a nuber here:");
int num;
if (in.hasNextInt()){
num =in.nextInt();
if(num % 2 == 0){
System.out.print("this is even!!");
} else{
System.out.println("this is odd!!");
}
} else {
System.out.print("pleas enter an integer only!!!");
num = in.nextInt();
if(num % 2 == 0){
System.out.print("this is even second check!!");
} else{
System.out.println("this is odd second check!!");
}
}
here is the code but i have some mistakes in there. it brings an error when input is not an int. pleas help with this, thanks in advance!
Try the below code, it will end only if its a valid Integer otherwise it will keep asking for Integer and I think you are looking for the same.
public void checkInt() {
Scanner scanner = new Scanner(System.in);
System.out.println("Eneter a nuber here:");
try {
int num = scanner.nextInt();
if (num % 2 == 0) {
System.out.print("this is even!!");
} else {
System.out.println("this is odd!!");
}
} catch (InputMismatchException e) {
System.out.println("pleas enter an integer only!!!");
checkInt();
}
}
You must read user input as String. Then, inside a try/catch block, make a casting to integer (Integer.parseInt()), if throws a exception is because is not a number.
May be a stupid way but this can solve your problem:
String x;
x = "5";//or get it from user
int y;
try{
y = Integer.parseInt(x);
System.out.println("INTEGER");
}catch(NumberFormatException ex){
System.out.println("NOT INTEGER");
}
Edited:
The program will try to convert the string to integer. If it is integer it will succeed else it will get exception and be caught.
Another way is to check the ASCII value.
To continue till integer is encountered:
String x;
Scanner sc = new Scanner(System.in);
boolean notOk;
do{
x = sc.next();
notOk = check(x);
}while(notOk);
System.out.println("Integer found");
}
private static boolean check(String x){
int y;
try{
y = Integer.parseInt(x);
return false;
}catch(NumberFormatException ex){
return true;
}
}
import java.util.Scanner;
public class Test {
public static void main(String args[] ) throws Exception {
Scanner sc=new Scanner(System.in);
if(sc.hasNextInt())
System.out.println("Input is of int type");
else
System.out.println("This is something else");
}
}
So I've recently learned exception handling for Java and I'm still trying to get used to it and all but I feel like I'm missing something. I was doing an assignment for my class and the compiler doesn't like my code.
I'm supposed to be making a Calculator that takes in an operator and then a number, and if the operator (+, -, *, /) given is not one of the aforementioned four, then an exception is thrown.
I used try-catch but for some reason the try and catch aren't recognizing each other unless I place them next to each other which isn't really what I want.
My question is really: Is there a way for my try and catch to recognize each other without being right next to each other, so I can run code in-between them? Or is that impossible and I'm doing it all wrong?
Here's my code so far:
import java.util.*;
public class Calculator
{
public static void main(String[] args)
{
String operatorInput;
double numberInput;
String userRedo = "Y";
double result = 0.0;
Scanner input = new Scanner(System.in);
System.out.println("Type in an arithmetic operator of your choice and press enter.");
System.out.println("Then, please type in a number that will undergo the operation.");
while((userRedo.toUpperCase()).compareTo("Y")==0)
{
try
{
operatorInput = input.nextLine();
if(operatorInput.compareTo("+")!=0||operatorInput.compareTo("-")!=0||
operatorInput.compareTo("*")!=0||operatorInput.compareTo("/")!=0)
{
throw new UnknownOperatorException("Unknown operator!");
}
}
numberInput = input.nextDouble();
if(operatorInput.compareTo("+")==0)
{
result += numberInput;
} else if(operatorInput.compareTo("-")==0)
{
result -= numberInput;
} else if(operatorInput.compareTo("*")==0)
{
result = result * numberInput;
} else
{
result = result / numberInput;
}
System.out.println("\nresult "+operatorInput+" "+numberInput+"= ");
System.out.println("Updated result: "+result);
System.out.println("Again? (y/n)");
userRedo = input.nextLine();
catch(UnknownOperatorException e)
{
System.out.println(e.getMessage());
}
}
}
}
And here's the exception class I made:
public class UnknownOperatorException extends Exception
{
public UnknownOperatorException()
{
super("Please select an actual operator and try again: ");
}
public UnknownOperatorException(String message)
{
super(message);
}
}
They have to be next to each other. There's a few things you could do:
Move the } at the commented line down a ways, like this
while((userRedo.toUpperCase()).compareTo("Y")==0)
{
try
{
operatorInput = input.nextLine();
if(operatorInput.compareTo("+")!=0||operatorInput.compareTo("-")!=0||
operatorInput.compareTo("*")!=0||operatorInput.compareTo("/")!=0)
{
throw new UnknownOperatorException("Unknown operator!");
}
}//this one here
Take that and move it to here
System.out.println("\nresult "+operatorInput+" "+numberInput+"= ");
System.out.println("Updated result: "+result);
}// put it here
Then take these two lines
System.out.println("Again? (y/n)");
userRedo = input.nextLine();
And move them below the catch:
catch(UnknownOperatorException e)
{
System.out.println(e.getMessage());
}
System.out.println("Again? (y/n)");
userRedo = input.nextLine();
}
}
That will let your while loop still sort of function and make your try/catch work. You might need to tweak things a bit to make them work right though
In order for try/catch to work, as Ghost says in a comment, you will need to put them next to each other.
And the code above has some problems...
maybe this works.
public static void main(String[] args) {
String operatorInput=null;
double numberInput;
String userRedo = "Y";
double result = 0.0;
Scanner input = new Scanner(System.in);
System.out.println("Type in an arithmetic operator of your choice and press enter.");
System.out.println("Then, please type in a number that will undergo the operation.");
while ((userRedo.toUpperCase()).compareTo("Y") == 0) {
try {
operatorInput = input.nextLine().trim();
if (operatorInput.compareTo("+") != 0
&& operatorInput.compareTo("-") != 0
&& operatorInput.compareTo("*") != 0
&& operatorInput.compareTo("/") != 0) {
throw new UnknownOperatorException("Unknown operator!");
}
} catch (UnknownOperatorException e) {
System.out.println(e.getMessage());
continue;
}
numberInput = Double.parseDouble(input.nextLine());
if (operatorInput.compareTo("+") == 0) {
result += numberInput;
} else if (operatorInput.compareTo("-") == 0) {
result -= numberInput;
} else if (operatorInput.compareTo("*") == 0) {
result = result * numberInput;
} else {
result = result / numberInput;
}
System.out.println("\nresult " + operatorInput + " " + numberInput + "= ");
System.out.println("Updated result: " + result);
System.out.print("Again? (y/n) : ");
userRedo = input.nextLine();
}
input.close();
}
public class Building implements CarbonFootprint {
//implement 4a
void getCarbonFootprint(){
System.out.println("Kim Byers, CSIS 505, Exception Handling, Assignment1");
//Building display
double Bill;
}
//class variables
double monthlyElectricBill;
double monthlyGasBill;
//constructor
public void Building(double monthlyElectricBill, double monthlyGasBill) {
monthlyElectricBill = ([monthyly Electric Billmonth;
monthlyGasBill = monthlyGasBill;
//Constructor
//set method statements
}
I'm wondering how do I go about validating this code so the input can only be an int and between a min and max? So far I can only stop the input being less than 1 and whatever maximum is used. But I cant seem to create a scenario where if the user inputs anything other than between the max and min (e.g. "AAA") it loops. I keep getting an Input Mismatch error. Any help would be greatly appreciated!
private static int getUserOption(String prompt, int max) {
int h;
do {
Scanner sc = new Scanner(System.in);
System.out.print(prompt);
h=sc.nextInt();
if(!sc.hasNextInt()) {
System.out.println("Invalid option. Try again!:");
}
} while(h<1 || h>max);
return h;
}
The loop is breaking because the nextInt() method is throwing an exception, which terminates the method early.
One option would be to use a try / catch block to trap the exception:
private static int getUserOption(String prompt, int max) {
int h = 0;
do {
Scanner sc = new Scanner(System.in);
System.out.print(prompt);
try {
h=sc.nextInt();
} catch (InputMismatchException e) {
System.out.println("Invalid option. Try again!:");
}
}while(h<1 || h>max);
return h;
}
You Can try this Code !
Scanner sc = new Scanner(System.in);
int number;
do {
System.out.println("Please enter a valid number: ");
while (!sc.hasNextInt()) {
System.out.println("Error. Please enter a valid number: ");
sc.next();
}
number = sc.nextInt();
} while (!checkChoice(number));
private static boolean checkChoice(int choice){
if (choice <MIN || choice > MAX) { //Where MIN = 0 and MAX = 20
System.out.print("Error. ");
return false;
}
return true;
}
Ref. Validating input with while loop and scanner
a few points:
1. to check if the input is less than a min value just add int min to the method signature.
2. to check if input is an int, catch InputMismatchException.
The revised code would be:
private static int getUserOption(String prompt, int max, int min) {
int h;
do {
Scanner sc = new Scanner(System.in);
System.out.print(prompt);
try {
h=sc.nextInt();
} catch (InputMismatchException e) {
System.out.println("Invalid option. Try again!:");
}
} while(h<min || h>max);
return h;
}
I couldn't understand if you want to keep asking until the user types a valid answer or just ask once. The while block suggests to keep asking until is a valid input.
Here is a small snippet that what you request. I suggest that you read some books, there a plenty of suggestions at SO.
public static class InvalidUserException extends Exception {
public InvalidUserException(String message) {
super(message);
}
public InvalidUserException(String message, Throwable cause) {
super(message, cause);
}
}
private static int getIntFromScanner(int max) throws InvalidUserException {
int nextInt = 0;
Scanner sc = new Scanner(System.in);
try {
nextInt = sc.nextInt();
} catch (InputMismatchException e) {
throw new InvalidUserException("Input must be a valid Integer", e);
}
if (nextInt > max) {
throw new InvalidUserException(
"Input is bigger than allowed! Max: " + max + " Input: "
+ nextInt);
}
return nextInt;
}
public static int getUserOption(String prompt, int max) {
System.out.println(prompt);
do {
try {
return getIntFromScanner(max);
} catch (InvalidUserException e) {
System.out.println("Invalid option. Try again ("
+ e.getMessage() + ")");
}
} while (true);
}
public static void main(String[] args) {
int userOption = getUserOption("Gimme less than or equal 6!", 6);
System.out.println("You gave me " + userOption);
}