I am trying to write some kind of a stack calculator.
Here is a part of my code where I am handling a push command. I want to push integers only, so I have to get rid of any invalid strings like foobar (which cannot be parsed into integer) or 999999999999 (which exceeds the integer range).
strings in my code is a table of strings containing commands like POP or PUSH, numbers, and random clutter already split by white characters.
Main problem:
I've got difficulties with throwing an exception for long parseNumber = Long.parseLong(strings[i]); - I don't know how to handle the case, when strings[i] cannot be parsed into a long and subsequently into an integer.
while (i < strings.length) {
try {
if (strings[i].equals("PUSH")) {
// PUSH
i++;
if (strings[i].length() > 10)
throw new OverflowException(strings[i]);
// How to throw an exception when it is not possible to parse
// the string?
long parseNumber = Long.parseLong(strings[i]);
if (parseNumber > Integer.MAX_VALUE)
throw new OverflowException(strings[i]);
if (parseNumber < Integer.MIN_VALUE)
throw new UnderflowException(strings[i]);
number = (int)parseNumber;
stack.push(number);
}
// Some options like POP, ADD, etc. are omitted here
// because they are of little importance.
}
catch (InvalidInputException e)
System.out.println(e.getMessage());
catch (OverflowException e)
System.out.println(e.getMessage());
catch (UnderflowException e)
System.out.println(e.getMessage());
finally {
i++;
continue;
}
}
Long.parseLong(String str) throws a NumberFormatException if the string cannot be parsed by any reason. You can catch the same by adding a catch block for your try, as below:
catch ( NumberFormatException e) {
System.out.println(e.getMessage());
}
No need to worry. Long.parseLong() throws a NumberFormatException if it got other than a Number.
After reading your comments and answers I was able to come up with such a solution (this code is embedded inside the outside try-catch.)
if (strings[i].equals("PUSH")) {
// PUSH
i++;
if (strings[i].length() > 10) {
throw new OverflowException(strings[i]);
}
try{
parseNumber = Long.parseLong(strings[i]);
if (parseNumber > Integer.MAX_VALUE) {
throw new OverflowException(strings[i]);
}
if (parseNumber < Integer.MIN_VALUE) {
throw new UnderflowException(strings[i]);
}
number = (int)parseNumber;
stack.push(number);
}
catch (NumberFormatException n){
throw new InvalidInputException(strings[i]);
}
}
Related
I have a task to make a program that will add up all the valid integers in a file and to ignore anything that isn’t a valid int. I have to use Try and Catch.
File Numbers = new File("Numbers.txt");
Scanner readFile = null;
int i = 0;
int total= 0;
boolean success = false;
while(!success){
try {
readFile = new Scanner(Numbers);
while(readFile.hasNext()){
i = readFile.nextInt();
System.out.println(i);
total = i + total;
};
success = true;// Ends The loop
} catch (FileNotFoundException e1) {
System.err.println(Numbers.getName()+" does not exist");
}
catch(InputMismatchException e2){
System.err.println("Data incorrect type expecting an int found: " + readFile.nextLine());
readFile.next();
}
System.out.println("total is: " + total);
};
The problem is that the program gets caught in an infinite loop, where instead of going past the exception it just starts again.The task seems pretty straight forward, yet i don't know why it wont work?
You fall into infinite loop because when exception happens, the success variable didn't change its value to true. In order to do some action even when exception happens you should add the finnaly block. It could look like this:
try {
// do some stuff
} catch (Exception e) {
// catch the exception
} finally {
if (!readFile.hasNext()) success = true;
}
And by the way, never do this: catch (Exception e), I did it just for example sake. Instead always catch the specific exception. Because Exception is the most basic class in the exception hierarchy, so it will catch up all the exceptions, and unless you re-throw it you could have false feeling of "safiness". When you want to catch all the exceptions, you should do this:
try {
// do stuff
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
e.printStackTrace(); // or other approptiate action, i.e. log it.
}
Assume any of the following FileNotFound or InputMismatchException exceptions will raise, then your program wont change success to true. Thus it returns to the outer while loop and read the same file. Because nothing has changed the same Exception will be thrown again.
==> Endless loop.
To fix that I suggest to move the try/catch block to the inner while.
I created a number format try catch: which is something like this
try{
int blabla = sc.nextInt();
} catch (numberFormatException E) {
doSomething();
}
How can I go straight to the catch, if say, blabla > 100?
Can I go straight to the catch, without having a number format exception, and using if statements? The try catch is mainly for when a string is entered.
why do you need try catch ? you can simply use if statement
int blabla = sc.nextInt();
if(blabla > 100 )
doSomeThing();
UPDATED
as per your comment if you want to catch you can throw the exception like following
try{
int blabla = sc.nextInt();
if(blabla > 100)
throw new NumberFormatException();
} catch (NumberFormatException E) {
doSomeThing();
}
MORE UPDATE
after the Brian comment i realized I should update a bit more. Yes it is definitely wrong to throw an exception for other cases. like here if blabla > 100 then it is not a NumberFormatException. So the better case would be to create your own exception and throw and catch that. to create a custom exception you can see this answer
But i still think the if statement is good for your case.
This may be what you are trying to achieve.
try{
int blabla = sc.nextInt();
if (blabla > 100) {
throw new NumberFormatException();
}
} catch (NumberFormatException E) {
doSomething();
}
Try this.
try{
int blabla = sc.nextInt();
if(blabla > 100)
throw new NumberFormatException();
} catch (numberFormatException E) {
doSomething();
}
EDIT : Stay with if..else until and unless you have specific requirement to go with throw exception and catch it...
Please have a look at mine constructor below, I'm creating a Fraction from a String:
public Fraction(String str)
{
if(str.isEmpty())
{
throw new IllegalArgumentException("The str (String) parameter cannot be empty!");
}
int[] fractionData= new int[2];
String[] data = str.split("/");
try
{
if(data.length==0)
throw new IllegalArgumentException("The str (String) parameter cannot be empty");
}
catch (IllegalArgumentException ex)
{
System.out.println(ex.toString());
}
try
{
fractionData[0] = Integer.parseInt(data[0]);
}
catch (IllegalArgumentException ex)
{
System.out.println(ex.toString());
}
try
{
fractionData[1] = Integer.parseInt(data[1]);
if(fractionData[1]==0) throw new ArithmeticException("Denominator can't be 0");
}
catch (ArithmeticException ex)
{
System.out.println(ex.toString());
}
fractionData = normalize(fractionData[0],fractionData[1]);
this.numerator = fractionData[0];
this.denominator = fractionData[1];
}
I'm catching the IllegalArgumentException fine, but fail to catch the ArithemticException. I can test both successfully
#Test(expected=IllegalArgumentException.class)
public void testIllegalArgumenException() throws IllegalArgumentException
{
Fraction g = new Fraction("");
}
#Test(expected=ArithmeticException.class)
public void testArithmeticException() throws ArithmeticException
{
Fraction g = new Fraction(1/0);
}
Thanks the comments from #xp500 I've changed my code to:
public Fraction(String str)
{
if(str.isEmpty()) throw new IllegalArgumentException("The str (String) parameter cannot be empty!");
int[] fractionData= new int[2];
String[] data = str.split("/");
if (data.toString().matches("[a-zA-Z]+")) throw new NumberFormatException("only numbers allowed in the string");
fractionData[0] = Integer.parseInt(data[0]);
fractionData[1] = Integer.parseInt(data[1]);
if(fractionData[1]==0) throw new ArithmeticException("Denominator can't be 0");
fractionData = normalize(fractionData[0],fractionData[1]);
this.numerator = fractionData[0];
this.denominator = fractionData[1];
}
It doesn't quote "only numbers allowed in the string", but stops initializing the Fraction as 0/0 in case String with letters is used to initialize the Fraction and throws the other exceptions with quoted text. The lesson for me is: DON'T CATCH EXCEPTIONS UNLESS YOU'RE ACTUALLY DOING SOMETHING WITH THEM
Yo are catching ArithmeticException but you are not retrowing it(like other exceptions)
A couple of comments about the code.
Your usage of the exceptions is making the code unreadable and hard to follow. You should try to use less try catch blocks. I think it would be better if you wrote something along the lines of
if (data.length==0) {
System.out.println(ex.toString());
throw new IllegalArgumentException("The str (String) parameter cannot be empty");
}
and not catch that exception, since you want to tell the caller that an exception occured.
Also, fractionData[0] = Integer.parseInt(data[0]); throws a NumberFormatException, not IllegalArgumentException
The ArithmeticException isn't being thrown since you are catching it inside the constructor, and not rethrowing it. Please note that, after catching it, your fraction will be initialized in an invalid state, since
fractionData = normalize(fractionData[0],fractionData[1]);
this.numerator = fractionData[0];
this.denominator = fractionData[1];
will be executed. Again, you might want to rewrite those lines for something like
if(fractionData[1]==0) {
System.out.println(ex.toString());
throw new ArithmeticException("Denominator can't be 0");
}
You don't need to write throws Exception, in your test methods, since you are expecting an exception to be thrown, the method itself won't throw that exception.
I hope that helps!
I am checking if number the user entered is Zeckendorf and I want to display an exception if it is not, how do i do that? Also how do I convert the Zeckondorf to its decimal equivalent?
import java.util.Scanner;
public class IZeckendorfNumberConvertor {
static String number;
int zeckonderEquivalent;
static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
convertToZeckonderNumber();
isTrueZeckonderNumber();
}
private static boolean isTrueZeckonderNumber() {
System.out.println("Enter a Zeckonder Number:");
number = scanner.nextLine();
if (number.equals("10100"))
{
return true; }
else if (number.equals("010011") || number.equals("010100"))
{
return false; }
return false;
}
private static void convertToZeckonderNumber() {
}}
I advise you not to display an exception (i.e. trace and such) as it is very user Unfriendly.
You can use the throw syntax to throw a proper exception :
throw new Exception("Given number is not a Zeckendorf number");
but be sure to catch it and display a nice and clean message :
try {
// Your input code goes here
} catch (Exception e) {
System.out.println(e.getMessage());
}
Another easier option will be to just check the return value of the method and print the results accordingly.
I will recommend to use the latter solution as exceptions are used when something bad and unexpected happens in your program and you want to handle it gracefully. In your case the behavior is expected (i.e. user giving a wrong number) so checking the return value will be much clean and easier.
Use try catch block for catch an exception
try {
} catch (Exception e) {
e.printStackTrace();
}
Also use throw for throw a new exception
Assuming to really do want to display the exception, and not a more user friendly message, the first step is probably to get the exception as a string. Then you can do what you like with that string (echo to console, place in a javax.swing.JTextArea, email it, etc).
If you just want the message from the exception, then getMessage() will do:
try { ... }
catch(FooException e) {
String msg = e.getMessage();
}
However, if you want the whole exception, stack trace and all, you'll want something like this:
public static String stackTrace(Exception e) {
StringWriter w = new StringWriter();
e.printStackTrace(new PrintWriter(w));
return w.toString();
}
// ...
try { ... }
catch(FooException e) {
String st = stackTrace(e);
}
If you just want to echo the full stack trace to the console, there is the printStackTrace(), no-arg method:
try { ... }
catch(FooException e) {
e.printStackTrace();
}
If you want to take more control of the presentation of the stack trace you can get the details with:
try { ... }
catch(FooException e) {
StackTraceElement[] stes = e.getStackTrace();
// Do something pretty with 'stes' here...
}
You can just print a error message to the user saying that the input is wrong using a simple if.
if(yourCondition){
// Happy scenario
// Go shead
}else{
// Error Scenario
System.out.println("Error. Invalid Input.");
// If you persist to throw an exception, then you can do something like this
// throw new Exception("Exception Explanation"); // I've commented this, but you can uncomment it if needed
// But the advice is to display an error message, than throw a exception.
}
And regarding the conversion, you can convert binary to decimal like this
int i = Integer.parseInt(binaryString, 2); // 2 indicates the radix here, since you want to convert from binary.
With this code snippet you can convert the String into an integer :
int numberAsInt;
try {
numberAsInt = Integer.parseInt(number);
} catch (NumberFormatException e) {
//Will throw an Exception
}
If you want to create your own Exception class, you can do it like shown here or just throw a RuntimeException with
throw new RuntimeException("Your Message");
My opinion, you can try some thing like following
public static void main(String[] args) {
if(!isTrueZeckonderNumber()){
// your message should goes here
System.out.println("Your message");
}
}
If you really want to throws an exception do following
private static boolean isTrueZeckonderNumber() throws Exception{
System.out.println("Enter a Zeckonder Number:");
number = scanner.nextLine();
if (number.equals("10100")) {
return true;
} else{
throw new Exception("your message");
}
}
What do you mean you want to display an exception?
I would suggest just giving the user feedback instead, as exceptions are used more commonly for EXCEPTIONAL actions that are not supposed to happen.
However if you do want to, you can print a message explaining what happened.
try {
} catch (Exception e) {
System.out.println(e.getMessage());
}
I am encountering an error when user doesn't type anything into input statement. I thought of using Try/Catch blocks to instead throw exception to set boolAskRepeat to true which should skip to the end of the code and repeat the loop.
This doesn't work, and I believe I'm missing something but I'm not sure what... It still throws exception saying:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 0
at java.lang.String.charAt(Unknown Source)
at ITSLab03.main(ITSLab03.java:34)
Which is this line of code: inputStatus = input.readLine().toLowerCase().charAt(0);
What am I doing wrong here?
while (boolAskStatus == true)
{
System.out.print("Employment Status (F or P): ");
try
{
inputStatus = input.readLine().toLowerCase().charAt(0);
if (inputStatus == "f".charAt(0))
{
boolAskStatus = false;
String stringCheckSalary = null;
boolean boolCheckSalary = true;
while (boolCheckSalary == true)
{
// some code
}
outputData(inputName, inputStatus, calculateFullTimePay(inputSalary));
}
else if (inputStatus == "p".charAt(0))
{
// some code
outputData(inputName, inputStatus, calculatePartTimePay(inputRate, inputHours));
}
else boolAskStatus = true;
}
catch (IOException e) { boolAskStatus = true; }
}
You need to catch StringIndexOutOfBoundsException as well (If you observe the stack trace properly this is the exception you are getting)
catch (StringIndexOutOfBoundsException e) {
boolAskStatus = true;
}
(or)
catch Exception which catches all runtime exceptions
catch (Exception e) {
boolAskStatus = true;
}
The normal try catch pattern should look like this:
try
{
// code that is vulnerable to crash
}
catch (Specific-Exception1 e1)
{
// perform action pertaining to this exception
}
catch (Specific-Exception2 e2)
{
// perform action pertaining to this exception
}
....
....
catch (Exception exp) // general exception, all exceptions will be caught
{
// Handle general exceptions. Normally i would end the program or
// inform the user that something unexpected occurred.
}
By using .charAt(0), you are assuming that the String has a length > 0.
You could simplify this a bunch by just doing:
String entry = input.readLine().toLowerCase();
if (entry.startsWith("f")) {
...
}
else if ("entry".startsWith("p")) {
...
}
Your code doesn't work the way you want because input.readLine().toLowerCase().charAt(0) throws a StringIndexOutOfBoundsException, which is not an IOException, so the catch block never gets hit. You can make it work by changing the catch to
catch (StringIndexOutOfBoundsExceptione e) { boolAskStatus = true; }
But...
It's generally not a good idea to base your program's normal behaviour on exception handling. Think of exception throwing as something that could happen, but usually won't. Why not use something like:
final String STATUS_F = "f";
final String STATUS_P = "p";
String fromUser = null;
do {
String rawInput = input.readLine().toLowerCase();
if (rawInput.startsWith(STATUS_F)) {
fromUser = STATUS_F;
} else if (rawInput.startsWith(STATUS_P)) {
fromUser = STATUS_P;
}
} while (fromUser == null);
if (STATUS_F.equals(fromUser)) {
// do something
} else if (STATUS_P.equals(fromUser)) {
// do something else
} else {
// Shouldn't be able to get here!
throw new Exception("WTF!?");
}
It much easier for another person reading this to understand why the program loops and how the loop is controlled, in part because the code that figures out what the user is inputting and the code that decides what to do with that information are separated. Plus, you don't need to deal with exceptions.