normally when I get a user interaction from a keyboard I use class scanner to do so but the problem I noticed when using its methods is that it's not handling exception! For example
Scanner input = new scanner();
Int number = input.nextInt();
The above works good for all integer numbers but if the user mistakly entered a character or a string, it will throw an exception and stops executing the rest of the program.
My question is there any way to avoid this?
Thank you in advance.
Try to catch the exception. Or use the hasNextInt method to prevent the exception from being thrown in the first place.
try {
int number = input.nextInt();
} catch (InputMismatchException e) {
System.out.println("That wasn't a number!");
}
Perhaps you should catch the exception and ask the user again?
See http://www.functionx.com/java/Lesson14.htm for exactly your problem.
Related
I'm writing a Java application which allows the user to enter a number of integer values and insert them into an ArrayList. The user should be asked after each item is entered, whether to continue entering data or to exit the application.
As well as that I have to enter a double value to see the type of exception thrown. Once identified, to write a Try/Catch statement which deals with the specific exception and allows the user to continue entering data (rather than having the application crash).
Here's what I have so far:
import java.util.Scanner;
import java.util.ArrayList;
public class Tester{
public static void main(String[] args){
ArrayList<Integer> myArrayList = new ArrayList<Integer>();
Scanner input = new Scanner(System.in);
while (true) {
System.out.println("please enter an integer: ");
integer.add(input.next());
So far, I have creating the ArrayList and prompting the user for input done, now I'm having trouble with continuing to ask the user for input or asking them to stop the process (how do I do this?)
Also how do I write the try/catch block part? I understand that the 'try' part must contain statements that may cause an exception. So how can I write something like:
try {
if input = double
System.out.print("This is an error")?
}
catch(inputMismatchexception e){
....
}
This is what you need:
try{
myArrayList.add(input.nextInt());
}catch(InputMismatchException e){
}
catch(NoSuchElementException e1){
}
catch(IllegalStateException e2){
}
This will throw an InputMismatchError if the input is not an Integer, thus covering your Double input case.
After this, just prompt the user to confirm if they want to continue (something similar to what Ravi wrote in his answer).
I'm having trouble with continuing to ask the user for input or asking
them to stop the process
Inside your while loop
System.out.println("Do you want to continue ?? (Y/N) ");
String str = input.next();
if(str.equals("N")
{
break;
}
input.next() always give you a string, so what you need to do is using Integer.parseInt(input) and check for NumberFormatException.
import java.util.Scanner;
import java.util.ArrayList;
public class Tester{
public static void main(String[] args){
ArrayList<Integer> myArrayList = new ArrayList<Integer>();
Scanner input = new Scanner(System.in);
while (true) {
System.out.println("please enter an integer: ");
try {
int value = Integer.parseInt(input.next());
myArrayList.add(value);
} catch (NumberFormatException e) {
// TODO whatever you want to do here
}
}
}
You are going down a wrong path: you intend to use exceptions to control the flow of your program.
That is possible; but not regarded "good practice" in java.
As the name says, exceptions are for exceptional (aka error) scenarios. But the user wanting to stop the program - that is not an exceptional thing; that should be a core part of your logic!
In that sense: simply use your Scanner object to ask the user for string. And before turning those strings into numbers; you could check if the string is empty for example. Or if the string is equalIgnoreCase() to "quit". Allowing the user to stop the program by just hitting "enter", or by typing "quit".
For the record: you could also use exceptions; just going for Integer.parseInt("any string that is not a int number") will throw a NumberFormatException.
But as said: catching those and assuming the user did that on purpose to the end the loop is a bad idea. What if the user didn't pay attention; made a typo and didn't want to stop?! Wouldn't it be better if you told him "you didnt enter a valid number, try again"?
I am making a basic application where it trains your math skills. I have this code:
while (true)
{
try
{
int userAnswer;
System.out.println("Type quit to exit to the menu!");
int randInt = r.nextInt(num2);
System.out.println(num1 + " + " + randInt + " =");
userAnswer = in.nextInt();
if(userAnswer == num1 + randInt) System.out.println("Correct!");
else System.out.println("Wrong!");
break;
}
catch(Exception e)
{
}
}
When someone prints out a d or something in the answer, the try catch goes. But, then it goes to the while loop and repeatedly spams Type quit to exit to the menu and then something like 1 + 2 = infinitely... I think I know what's wrong, userAnswer has been assigned already as something that throws an exception that goes to the catch and it just keeps printing those and goes to the catch and goes back because userAnswer is already assigned. I think this is what is happening, I could be wrong. Please help!
EDIT: I forgot to make this clear, but I want the question to be re-printed again, exiting out of the loop goes to a menu where you can't get the question back, I want it to redo what's in the try catch...
You should never catch an Exception without handling it.
catch(Exception e)
{
System.out.println("An error has occured");
break;
}
This should stop your program from looping infinitely if an Exception occurs.
If user input comes as letter it will get an exception because you are trying to read(parse) as integer. So your catch clause is in the loop you have to write break in there to go out from loop.
Still i will suggest you to getline as string and than compare with your cli commands (quit in your case) than you can try to parse it as an integer and handle loop logic.
You're not breaking the while loop if there is a mismatch
while(true)
{
try
{
}
catch(InputMisMatchException e)//I suggest you to use the exact exception to avoid others being ignored
{
System.out.println("Thank you!");
break;//breaks the while loop
}
}
Yoy're not breaking the loop in case of Exception occurs.
Add break; statement in the catch block to run your program without going to infinite loop, in case exception occurs.
Since the given answers don't match your requirement I'll solve that "riddle" for you.
I guess what you didn't knew is that the scanner won't read the next token if it doesn't match the expectation. So, if you call in.nextInt() and the next token is not a number, then the scanner will throw an InputMismatchException and keeps the reader position where it is. So if you try it again (due to the loop), then it will throw this exception again. To avoid this you have to consume the erroneous token:
catch (Exception e) {
// exception handling
in.next();
}
This will consume the bad token, so in.nextInt() can accept a new token. Also there is no need to add break here.
Mind that in.next() reads only one token, which is delimited by a whitespace. So if the user enters a b c, then your code will throw three exception and therefore generate three different question befor the user can enter a number. You can avoid that by using in.nextLine() instead. But this can lead into another problem: Scanner issue when using nextLine after nextXXX, so pay attention to that :).
This question already has answers here:
try/catch with InputMismatchException creates infinite loop [duplicate]
(7 answers)
Closed 7 years ago.
If I type in letter for the first Scanner statement i get "error!!" and "enter a number" but cannot input another number.I am a beginner and do not know whether an input statement can be used within a catch statement
import java.util.InputMismatchException;
import java.util.Scanner;
public class excep {
public static void main(String args[]){
int n;
Scanner input=new Scanner(System.in);
try{
System.out.println("ENTER A NUMBER: ");
n=input.nextInt();
}
catch(InputMismatchException e){
System.out.println("ERROR!!! \nENTER A NUMBER :");
n=input.nextInt();
}
}
}
You must have to eat or remove characters from the buffer before you restart input. For the sake of simplicity, your code should look alike :
while(true) {
Scanner input=new Scanner(System.in);
try {
System.out.println("ENTER A NUMBER: ");
n=input.nextInt();
break;
}catch(InputMismatchException e) {
System.out.println("ERROR!!! \nENTER A NUMBER :");
input.next(); // eat some chars
}
}
The biggest problem with your approach is that if nextInt() fails because the user did not enter a valid integer, the scanner does not advance. The scanner has a pointer that points to the next character to read from the input. When you use nextInt(), if the next "token" is an integer, the scanner will advance the pointer past the integer. But if it isn't an integer, an exception is thrown--and the pointer stays in the same place as before. So when you catch the exception, then call nextInt(), the scanner tries to read the same invalid integer that it just tried to read last time.
To skip over the bad integer, you can say input.next() to skip over one token, or input.nextLine() to skip over the entire remainder of the input line, before trying to read another integer. (Both of these return String results, but you can discard the result since it's not important to you).
However, this is not really a good way to use try/catch. If the user is having a bad day and enters another invalid integer, the scanner will throw an exception, and it will not be caught, since you are not in the try when the second exception is thrown. catch doesn't loop back and catch it again. The best idiom for this is a loop:
boolean validIntegerEntered = false;
System.out.println("ENTER A NUMBER: ");
while (!validIntegerEntered) {
try {
n=input.nextInt();
validIntegerEntered = true; // will not get here if nextInt()
// throws an exception
}
catch (InputMismatchException e) {
input.nextLine(); // let the scanner skip over the bad input
System.out.println("ERROR!!! \nENTER A NUMBER :");
// don't call nextInt() here; loop back, and nextInt() will be called
// in the try statement
}
}
Syntactically, Yes you can but you shouldn't use it. Why?
input.nextInt(); can throw InputMismatchException or NoSuchElementException or IllegalStateException if the scanner is closed.
If any of those exceptions occur within the catch block, you are not handling them. You should probably look at how to implement a retry catch
You are using the input.nextInt(), means it can only accepts int values.If you want to enter string values then better to use input.nextine().
In your code in catch block you are using again input.nextInt() but scanner has already wrong input in it that why it throw the exception.If you want to take input inside catch block then try the below code:
catch(InputMismatchException e){
System.out.println("ERROR!!! \nENTER A NUMBER :");
Scanner input1=new Scanner(System.in);
n=input1.nextInt();
System.out.println("Inside catch:"+n);
}
Here is my code for inputting a student number:
When the user inputs the number in a unexpected format I will ask them to reinput by recursion. But it ends up with an infinitive recursion. Why?
private static int inputStudentNumber(){
System.out.println("Enter the student number:");
int studentNum;
try {
//Scanner in initialized before calling this method
studentNum = in.nextInt();
return studentNum;
} catch(Exception e) {
System.out.println("Invalid input, it can only be integer.");
return inputStudentNumber();
}
}
Take a closer look at the javadocs for Scanner.nextInt:
This method will throw InputMismatchException if the next token cannot be translated into a valid int value as described below. If the translation is successful, the scanner advances past the input that matched. (emphasis added)
If it's not successful, the scanner isn't advanced. That means that if you try to invoke nextInt() again, you'll be trying to get an int from the same token as before, and you'll once again get an InputMismatchException.
Your code basically says: try to read the next token as an int. If that fails, recurse to try to read the token as an int again. If that fails, recurse to try to read the token as an int again. If that fails... (and so on, until you get a StackOverflowException from too much recursion).
If you want to use recursion for this, you should probably use next() to skip to the next token. And only catch InputMismatchException, so that you won't also catch NoSuchElementException (which won't happen for System.in, but is good practice in general -- what if you later decide to read from a file, and that file has reached its end?).
} catch(InputMismatchException e) {
System.out.println("Invalid input, it can only be integer.");
in.next(); // skip this token
return inputStudentNumber();
}
An even better approach would be to avoid using the exception to control your logic in the first place. To do this, you'd have to know ahead of time whether nextInt will succeed. Luckily for you, hasNextInt() lets you do exactly that!
private static int inputStudentNumber() {
System.out.println("Enter the student number:");
if (in.hasNextInt()) {
return in.nextInt();
} else {
System.out.println("Invalid input, it can only be integer.");
in.next(); // consume the token
return inputStudentNumber();
}
}
The advantage here -- besides the general "don't use exceptions for control flow" advice -- is that the base case is super clear. If there's an int ready, that's your base case; if not, you have to advance the scanner and try again.
The problem is that if a non-integer is entered as input, then that input is not consumed by the scanner. So you just keep reading it.
You may want to just read the input as a string and then try to convert it separately.
Your problem is probably that in.nextInt() is throwing an Exception. A code smell that I see is that you use:
catch(Exception e) {
....
}
The best practice here is to only catch the specific Exception you are expecting, so it should be:
catch(InputMismatchException e) {
....
}
If you do this, then whatever in.nextInt() is throwing will properly propagate to the top, and you will probably see that in is not initialized or some such problem.
See here for the Exceptions that nextInt() can throw.
http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#nextInt()
try this...
private static int inputStudentNumber(){
System.out.println("Enter the student number:");
int studentNum;
int var = 1;
while(var ==1)ยด
{
try{
studentNum = in.nextInt();
var=0;
return studentNum;
}catch(Exception e){
System.out.println("Invalid input, it can only be integer.");
var=1;
return inputStudentNumber();
}
}
}
I need help Using Exception handling with Wrong User Input. I am creating a text based game that welcomes the User and then goes to the main menu. It then tell the User the options, and then look for User input. For some Reason, whenever I input 1 or 2, It says: "Your input is invalid, please try again" And goes back to the choices. I don't know exactly where I am going wrong, hopefully someone can help me. Also, it won't catch the Mismatch Exception either. Hope you can Help! Thanks, Shandan
public static void main(String[] args) {
System.out.println("Welcome to Spec Ops!");
System.out.println("Please state your name:");
Scanner name = new Scanner(System.in);
String Name = name.next();
System.out.println("Hello "+Name);
mainMenu();
}
public static void mainMenu() {
System.out.println("1. Story Mode");
System.out.println("2. Infinant Combat");
Scanner input = new Scanner(System.in);
Object Selection = input.nextInt();
boolean validOption = true;
Integer x;
try {
x = (Integer)Selection;
} catch(ClassCastException cce){
System.out.println("Your input is invalid, please try again");
validOption = false;
} catch(InputMismatchException ime){
System.out.println("Your input is invalid, please try again");
validOption = false;
}
if(validOption) {
System.out.println("Hello!");
}
else {
mainMenu();
}
}
}
Scanner.nextInt returns ant int, so there is no need to go Object selection = scanner.nextInt(), and then cast to an int, you can merely have int selection = scanner.nextInt() and surround that in a try catch that chatches java.util.InputMismatchException, which is the exception thrown when the user types a letter and not an number
You can temporarily change your code and use the Pokemon exception handling and check the stack trace to see what kind of exception you should implement:
try {
//do something
} catch(Exception e) {
//Gotta catch 'em all!
e.printStackTrace();
}
Once you know the exact exception, put some breakpoints and refactor your code accordingly.
Also, you don't have to control the flow of your program by changing your boolean variable inside the catch blocks:
boolean isValidOption = false;
Integer x;
try {
x = (Integer)Selection;
isValidOption = true;
} catch...
When you read the name in you are using scanner.next(). This does not read in the end of line character, so when you call scanner.nextInt() it reads the new line and fails to parse as an int.
You should change the name reading to scanner.nextLine() and if you want to handle invalid int inputs from the user, the call to nextInt needs to be in your try block and catch the InputMismatchException instead of the ClassCastException.