Try catch and user input - java

This is a question for a homework assignment involving a try/catch block. For a try/catch I know that you place the code you want to test in the try block and then the code you want to happen in response to an exception in the catch block but how can i use it in this particular case?
The user enters a number which is stored in userIn but if he enters a letter or anything besides a number I want to catch it. The user entered number will be used in a switch statement after the try/catch.
Scanner in = new Scanner(System.in);
try{
int userIn = in.nextInt();
}
catch (InputMismatchException a){
System.out.print("Problem");
}
switch(userIn){...
When I try to compile, it returns symbol not found, for the line number corresponding to the beginning of the switch statement, switch(userIn){. A few searches later I find that userIn cannot be seen outside the try block and this may be causing the error. How can I test userIn for correct input as well as have the switch statement see userIn after the try/catch?

The int userIn is inside the try-catch scope, and you can use it only inside the scope not outside.
You must declare it outside the try-catch brackets:
int userIn = 0;
try{
userIn = ....
}.....

Use something like:
Scanner in = new Scanner(System.in);
int userIn = -1;
try {
userIn = in.nextInt();
}
catch (InputMismatchException a) {
System.out.print("Problem");
}
switch(userIn){
case -1:
//You didn't have a valid input
break;
By having something like -1 as the default value (it can be anything that you won't receive as input in the normal run, you can check if you had an exception or not. If all ints are valid, then use a boolean flag which you can set in the try-catch blocks.

Try something like this
int userIn = x; // where x could be some value that you're expecting the user will not enter it, you could Integer.MAX_VALUE
try{
userIn = Integer.parseInt(in.next());
}
catch (NumberFormatException a){
System.out.print("Problem");
}
This will cause and exception if the user entered anything than numbers because it will try to parse the user input String as a number

Related

Java: Program crashes after inputting two bad values

I coded a program, that calculates the gcd (greatest common divisor) and lcm (least common multiple). Everything works fine except the try {...} catch(...) {...}. Here is the part of the code that doesn't work as I want it to:
try {
num1 = Integer.parseInt(sc.nextLine());
}
catch(Exception e) {
System.out.println("Your input is not an integer (number w/o decimals)! Try again.");
System.out.print("Enter your first number: ");
num1 = Integer.parseInt(sc.nextLine());
}
When I input e.g. letters, it says:
Your input is not an integer (number w/o decimals)! Try again.
Enter your first number:
But when I type letters the second time, the program crashes:
Exception in thread "main" java.lang.NumberFormatException: For input string: "asdf"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:68)
at java.base/java.lang.Integer.parseInt(Integer.java:658)
at java.base/java.lang.Integer.parseInt(Integer.java:776)
at GCDLCMgetter.main(GCDLCMgetter.java:56)
It is probably a very simple mistake I made but I can't figure it out...
Thank you
Your second parseInt method call is not in try catch block. You need to use a loop for this kind of logic.
It's because your second prompt is inside the catch block. Instead of prompting again inside the catch block, you want to wrap the entire code section in a loop so it comes back around to the try block for the prompt again.
Something like:
boolean repeat = true;
while(repeat){
try{
//Prompt for input
repeat = false;
}catch(Exception e) {
//Display error message
}
}
When the first time you give letters it goes into catch block. Displays the error message. And then executes the line num1 = Integer.parseInt(sc.nextLine());
Again you have entered the letters, but this time there is no try-catch block to handle this. So it throws error.
In your code, it gets executed twice:
Reads a Line at try{...}
There is an Exception
The Exception is handled by the catch(Exception e){...}
The num1 = Integer.parseInt(sc.nextLine()); inside the catch(Exception e){...} cannot be handled. It's not placed inside try{}.
Execution finished because the last exception cannot be handled by any catch.
It seems you're using Scanner, I would recommend you using a loop whis way:
while (sc.hasNextLine()){
try {
System.out.print("Enter your first number: ");
num1 = Integer.parseInt(sc.nextLine());
}
catch(Exception e) {
System.out.println("Your input is not an integer (number w/o decimals)! Try again.");
}
}
If you're managing integers, it would be interesting using Scanner.nextInt()
while (sc.hasNextInt()){
try {
System.out.print("Enter your first number: ");
num1 = sc.nextInt());
}
catch(Exception e) {
System.out.println("Your input is not an integer (number w/o decimals)! Try again.");
}
}

How to use Try/Catch to prevent String input where an Int is needed

/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package freetime;
import java.util.InputMismatchException;
import java.util.Scanner;
/**
*
* #author Andy
*/
public class NewClass {
public static void main(String[] args){
Scanner scan=new Scanner(System.in);
int userInput=0,notInt=0,newInput=0;
System.out.println("Enter a integer number");
while (notInt == 0){
try {
newInput=scan.nextInt();
userInput=newInput;
if (userInput != newInput){
notInt=0;
}
if (userInput == newInput){
notInt=1;
}
}
catch(InputMismatchException e){
System.out.println("That is not an integer, please try again." );
}
}
System.out.println(userInput);
}
}
I am trying to prevent a string input and allow the user to re input as an int. i cannot seem to get it to work properly, i also did this without the while loop. I think my understanding of how the Try Mismatch functions work is causing some issues.
Thanks for the help.
Scanner scan=new Scanner(System.in);
int userInput=0,notInt=0,newInput=0;
boolean runL=true;
while (runL){
System.out.println("Enter a integer number");
if (scan.hasNextInt()){
userInput=scan.nextInt();
runL=false;
}
else {
System.out.println("That is not an integer, please try again.");
}
}
System.out.println(userInput);
So i changed the code to this but I am still running into the loop continuing to go after something other than an int is entered. What am i doing wrong?
int userInput=0,notInt=0,newInput=0;
boolean runL=true;
while (runL){
Scanner scan=new Scanner(System.in);
System.out.println("Enter a integer number");
if (scan.hasNextInt()){
userInput=scan.nextInt();
runL=false;
}
else {
System.out.println("That is not an integer, please try again.");
}
}
System.out.println(userInput);
I've found the problem, I needed to create the scanner object inside of the While loop. Thanks for the help!
I think my understanding of how the Try Mismatch functions work is causing some issues.
You are probably right there ...
When I remove some of the "strange" code from your try / catch statement it looks like this:
try {
newInput = scan.nextInt();
// do stuff
} catch (InputMismatchException e){
// do other stuff
}
Here's what that actually means:
Call scan.nextInt()
If the call succeeds (i.e. it doesn't throw an exception), then:
assign the result to newInput
"do stuff"
If the call failed, AND it threw a InputMismatchException, then:
"do other stuff"
So, based on that, you don't need to do anything in "do stuff" to test if you just got a valid input. You know that is the case.
And likewise, any stuff that needs to be do in the case where you didn't get a valid input should be in "do other stuff".
Having said that, Jon Skeet's suggestion to look at the hashNextInt method is spot on. If you use that the right way, you won't get an exception at all. The code will be much simpler.
And Jon is also correct that you should be using the boolean type for your true / false logic. (That is what the type is intended for!)
Use Integer.parseInt(input) in try block.
If input is not an int, then it will throw an exception and catch the exception in catch{} block.
Your while loop should look like this:
while (notInt == 0){
try {
newInput=Integer.parseInt(scan.nextLine());
userInput=newInput;
notInt=1;
}
catch(NumberFormatException e){
System.out.println("That is not an integer, please try again." );
}
}
Your code doesn't work because when a InputMismatchException is thrown, the token that causes the exception isn't actually read. So the loop is reading the same thing every iteration.
nextLine however, almost always reads the whole line as a string (except when there's no line). You put the string that is read into Integer.parseInt to turn it into an int. If it can't be turned into an int, a NumberFormatException will be thrown.
However, you should not use exceptions as a way of validating inputs because it's slow. You can try this approach with regex:
while (notInt == 0){
String line = scan.nextLine();
Pattern p = Pattern.compile("-?\\d+");
if (p.matcher(line).matches()) {
userInput = Integer.parseInt(line);
notInt = 1;
} else {
System.out.println("Please try again");
}
}

How to scan an indefinite list of numbers from a single input?

How to scan an indefinite list of numbers from a single input?
I did a brief google search and found hasNextInt(), but it only stops scanning if the last input is NOT an integer, while I need it to stop if it's the last integer. For example, it will continue to ask me if my list ends with an integer.
My code:
System.out.println("Enter a list of numbers");
int n = 0;
while (input.hasNextInt()){
n = input.nextInt();
List.push(n);
}
List.displayStack();
You may use hasNext() instead. Then parse the input and get the number -
int n=0;
Scanner input = new Scanner(System.in);
while (input.hasNext()) {
try {
n = Integer.parseInt(input.nextLine());
//do something eg.- you have done
//List.push(n);
} catch (NumberFormatException nfe) {
//handle exception
}
}
Now if the input not is an integer then it will not stop. Rather it will go for the catch block. And since the catch block is still in the while loop so you can take a new input still now.
Hope it will help.
Thanks a lot

try-catch statement not returning to try block when catching exception

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.

try/catch infinite loop? [duplicate]

This question already has answers here:
How to handle infinite loop caused by invalid input (InputMismatchException) using Scanner
(5 answers)
Closed 5 years ago.
Help, I am completely new to java and I am trying to create a loop that will ask for an input from the user which is to be a number. If the user enters anything other than a number I want to catch the exception and try again to get the correct input. I did this with a while loop however it does not give the opportunity after the error for the user to type in anything it loops everything else but that. Please help me to see understand what is wrong and the correct way to do this... Thank you. This is what I have:
import java.util.Scanner;
import java.util.InputMismatchException;
public class simpleExpressions {
public static void main (String[] args) {
Scanner keyboard = new Scanner(System.in);
while ( true ) {
double numOne;
System.out.println("Enter an Expression ");
try {
numOne = keyboard.nextInt();
break;
} catch (Exception E) {
System.out.println("Please input a number only!");
} //end catch
} //end while
} //end main
while ( true )
{
double numOne;
System.out.println("Enter an Expression ");
try {
numOne = keyboard.nextInt();
break;
}
catch (Exception E) {
System.out.println("Please input a number only!");
}
This suffers from several problems:
numOne hasn't been initialized in advance, so it will not be definitely assigned after the try-catch, so you won't be able to refer to it;
if you plan to use numOne after the loop, then you must declare it outside the loop's scope;
(your immediate problem) after an exception you don't call scanner.next() therefore you never consume the invalid token which didn't parse into an int. This makes your code enter an infinite loop upon first encountering invalid input.
Use keyboard.next(); or keyboard.nextLine() in the catch clause to consume invalid token that was left from nextInt.
When InputMismatchException is thrown Scanner is not moving to next token. Instead it gives us opportunity to handle that token using different, more appropriate method like: nextLong(), nextDouble(), nextBoolean().
But if you want to move to other token you need to let scanner read it without problems. To do so use method which can accept any data, like next() or nextLine(). Without it invalid token will not be consumed and in another iteration nextInt() will again try to handle same data throwing again InputMismatchException, causing the infinite loop.
See #MarkoTopolnik answer for details about other problems in your code.
You probably want to use a do...while loop in this case, because you always want to execute the code in the loop at least once.
int numOne;
boolean inputInvalid = true;
do {
System.out.println("Enter an expression.");
try {
numOne = keyboard.nextInt();
inputInvalid = false;
} catch (InputMismatchException ime) {
System.out.println("Please input a number only!");
keyboard.next(); // consume invalid token
}
} while(inputInvalid);
System.out.println("Number entered is " + numOne);
If an exception is thrown then the value of inputInvalid remains true and the loop keeps going around. If an exception is not thrown then inputInvalid becomes false and execution is allowed to leave the loop.
(Added a call to the Scanner next() method to consume the invalid token, based on the advice provided by other answers here.)

Categories

Resources