So I'm writing code here just for fun but I've come up with an error that I just can't seem to fix. This block of code is supposed to take in an int... at first i had the hasNextInt() in the while loop alone to try and ensure i'm getting the correct input, but as fate would have it.. i got the exception. I then added a try catch to it thinking maybe i just did something wrong... and still i get the same error. I don't know whats wrong here. this is actually my 1st time using a try catch block (still kind of a noob). it looks good to me and i've looked at the documentation online and done some minor research but to no avail. can anyone identify whats wrong here?
check it out:
do{
System.out.println("How much AP do you want to allocate towards HP? ");
try {//added try catch... still throwing the exception..
while(!in.hasNextInt()){//this should've been enough, apparently not
System.out.println("That is not a valid input, try again.");
in.nextInt();
}
} catch (InputMismatchException e) {
System.out.print(e.getMessage()); //trying to find specific reason.
}
hpInput = in.nextInt();
}while(hpInput < 0 || hpInput > AP);
if i entered a string it would give me the "That is not a valid input, try again." line.. but the exception would still occur right after instead of just looping until an actual int is detected... help plz..
Your while loop should look something like this
while(!in.hasNextInt()){ // <-- is there an int?
System.out.println("That is not a valid input, try again.");
// in.nextInt(); // <-- there is not an int...
in.next(); // <-- this isn't an int.
}
Because the Scanner doesn't have an int.
You can't really validate the value in the Scanner until something has been input, but once it's input, it's too late to validate it...
Instead, you could use a second Scanner to validate the String result you are getting from the user via the keyboard, for example
Scanner kbd = new Scanner(System.in);
int result = -1;
do {
System.out.println("How much AP do you want to allocate towards HP? ");
String value = kbd.nextLine();
Scanner validate = new Scanner(value);
if (validate.hasNextInt()) {
result = validate.nextInt();
}
} while (result < 0);
Related
/*
* 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");
}
}
So the following code is like a simple game,where the objective to to guess the correct numbers(which are 1 to 5).Anything else is incorrect and the user is given a warning message if they enter similar numbers.The comments would explain the loops and variables declared.
The only problem I have with this code is that I inserted a try catch to take care of strings and that doesn't seem to work.If a string is entered,the while loop continues infinitely.
Also,I realize there are a loop pf looping and conditional statements present in my code,but I couldn't think of anything else.If you have any recommendations to reduce the number of loops and if statements,your help would be greatly appreciated.
public class Tries {
public static void main(String[]args)
{
boolean dataType=false;
int Inp;
Scanner a=new Scanner(System.in);
//The arraylist,List, contains the input that the user enters.Only correct input is entered(1 to 5).
ArrayList<Integer> List=new ArrayList<Integer>();
//This determines how many times the for loop is going to execute.Say the user enters 4,and enters 4 correct inputs,the program will exit.The variable num basically determines what the size of the arraylist List is going to be.
System.out.println("How many tries?");
int num=a.nextInt();
boolean datatype=false;
for(int j=0;j<num;j++)
{
//This while loop is for the try catch.
while(!datatype)
{
Scanner sc=new Scanner(System.in);
//This while loop ensures that the user re enters input when anything other than the correct numbers are entered.
while(List.size()!=num)
{
try
{
System.out.println("\nPick a number: ");
Inp=sc.nextInt();
if(Inp==1 || Inp==2 || Inp==3 || Inp==4 || Inp==5)
{
datatype=true;
System.out.println(j);
if(List.size()==0)
{
List.add(Inp);
}
else if(List.size()>0)
{
if(List.contains(Inp))
{
System.out.println("Already entered.Try again.");
}
else if(!List.contains(Inp))
{
List.add(Inp);
System.out.println("Added");
dataType=true;
System.out.println(List);
}
}
}
else
{
System.out.println("Option not available.");
datatype=false;
}
}
catch(Exception JavaInputMismatch)
{
System.out.println("Option not available.Try again.");
datatype=false;
}
}
}
}
}
}
So, when Inp=sc.nextInt(); fails because the user enters an invalid number, then an InputMismatchException gets thrown. Then you loop again, and eventually attempt to run Inp=sc.nextInt(); again.
The problem though is that the invalid number that was entered is still in the input stream waiting to be read. So in the next loop, when Inp=sc.nextInt(); is attempted again, it doesn't try to read in a new value, it just reads the previous invalid value without allowing you to type anything new. And this keeps happening over and over indefinitely.
The quick fix? You need to clear out the input stream to get rid of the invalid number before attempting to read a new one.
The simplest way to plug that fix in your program is by adding an sc.next(); call in your catch block like this:
catch(Exception JavaInputMismatch)
{
sc.next(); // clear the bad token. Without this, it loops infinitely.
System.out.println("Option not available.Try again.");
datatype=false;
}
There are certainly quite a few other changes/improvements I would make to the program, but I'll admit that I lack the motivation at the moment to address those. Hopefully this will at least unblock you.
EDIT:
I guess I can add a few high level suggestions that can help you:
As was already commented, you shouldn't have 2 Scanner instances reading from System.in.
I would recommend dropping the whole try-catch to detect an invalid number, and instead use sc.hasNextInt() to check before reading the number with sc.nextInt(). Even if you did keep the catch block, I would recommend you make the exception type as specific as possible (e.g. catch(InputMismatchException e)) instead of the catch-all Exception. Otherwise, you risk catching irrelevant exceptions and handling them the wrong way.
You should be able to drop the datatype boolean variable and its associated loop. It's enough that you are looping as long as your list is not full.
In fact, if I'm understanding this correctly, you can probably simplify your loops by only keeping the one that does while(List.size()!=num). I think you can safely get rid of the loop that does for(int j=0;j<num;j++).
Minor detail, but you can express if(Inp==1 || Inp==2 || Inp==3 || Inp==4 || Inp==5) more succinctly like this instead: if(Inp >= 1 && Inp <= 5).
And finally, the logic that determines whether to add the number to the list or not doesn't need to do a bunch of conditions based on the size of the list.
Something like this is sufficient:
if (List.contains(Inp)) {
System.out.println("Already entered.Try again.");
} else {
List.add(Inp);
System.out.println("Added");
System.out.println(List);
}
I hope this helps.
I want to take an integer input from the user. I am using a try-catch exception so that if the input is not an int it asks the user for another input. I have written the following code:
while (flag==true) {
try {
System.out.println("Enter the encryption key!");
k = input.nextInt();
flag = false;
}
catch (InputMismatchException ex) {
System.out.println("Please enter integer value!(");
}
}
But when an exception occurs the loop keeps on printing
"Enter the encryption key!"
"Please enter integer value!"
infinitely because the scanner input does not wait to take another input.
How can I tackle with this problem?
You could try to use
input.nextLine()
because then it waits until you press enter. But then you need to parse it to an int if i remember correctly.
You should call next inside the catch clause, this will solve the problem.
See the docs - Scanner:
When a scanner throws an InputMismatchException, the scanner will not
pass the token that caused the exception, so that it may be retrieved
or skipped via some other method.
Without having next in the catch clause, input.nextInt(); will keep reading the same token, adding next will consume that token.
You should go with suggestion of Maroun Maroun that looks more clean to me.
One other way is to re-initialize the Scanner in loop.
boolean flag = false;
while (!flag) {
try {
input = new Scanner(System.in);//Initialize it here
//....
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.
I'm helping a friend with a java problem. However, we've hit a snag. We're using Java.Util.Scanner.nextInt() to get a number from the user, asking continiously if the user gives anything else. Only problem is, we can't figure out how to do the error handeling.
What we've tried:
do {
int reloop = 0;
try {
number = nextInt();
} catch (Exception e) {
System.out.println ("Please enter a number!");
reloop ++;
}
} while(reloop != 0);
Only problem is, this loops indefinatly if you enter in something not a number.
Any help?
You can use hasNextInt() to verify that the Scanner will succeed if you do a nextInt(). You can also call and discard nextLine() if you want to skip the "garbage".
So, something like this:
Scanner sc = new Scanner(System.in);
while (!sc.hasNextInt()) {
System.out.println("int, please!");
sc.nextLine();
}
int num = sc.nextInt();
System.out.println("Thank you! (" + num + ")");
See also:
How do I keep a scanner from throwing exceptions when the wrong type is entered? (java)
The problem with your code, in addition to the unnecessarily verbose error handling because you let nextInt() throw an InputMismatchException instead of checking for hasNextInt(), is that when it does throw an exception, you don't advance the Scanner past the problematic input! That's why you get an infinite loop!
You can call and discard the nextLine() to fix this, but even better is if you use the exception-free hasNextInt() pre-check technique presented above instead.
if the number is non-int , exception will pop, if not reloop will become 1 , and loop will exit
int reloop = 0;
do {
try {
number = nextInt();
reloop ++;
} catch (Exception e) {
System.out.println ("Please enter a number!");
}}
while(reloop == 0);