I need to write a program that can validate user input as integer and prevent it from crashing whenever use input is not integer. So I am using try and catch here. However, I got an infinite loop when user input is a non-integer. Below is my code
do {
try {
a = sc.nextInt();
} catch (InputMismatchExpression e) {
System.out.println("This is not integer");
}
} while(a < 1 || a > 10);
Once the Scanner throws an exception, the existing value remains "unconsumed". To avoid this you need to add sc.next() line to consume the existing input and make Scanner await the next value from the user.
do {
try {
a = sc.nextInt();
} catch (InputMismatchExpression e) {
sc.next(); // this "consumes" the invalid input and throws away
System.out.println("This is not integer");
}
} while(a < 1 || a > 10);
If you actually want to break the loop, if user input is a non-integer, then you can simply add a flag value in your code :
int flag = 0;
do {
try {
a = sc.nextInt();
} catch (InputMismatchExpression e) {
System.out.println("This is not integer");
flag=1;
}
} while((a < 1 || a > 10)&&flag==0);
If flag=1, loop will break.
normaly use regex check user input
like :
String userInput = "1234567";
boolean isNumber = userInput.matches("^\\d+$");
System.out.println(isNumber);
Related
I'm trying to ask the user for a number and if they enter anything wrong (not an int between 1 and 99) then catch (to prevent crash if string) and loop until enter a right number. My loop is stuck in an endless loop somehow. Note: I do have the Scanner imported and the exception imported too.
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String result;
int number;
boolean done = false;
while (true) {
try {
System.out.println("Please select a number from 1 to 99.");
number = input.nextInt();
input.nextLine();
if (number >= 1 || number <= 99) {
result = checkNumber(number);
System.out.println(result);
break;
}
} catch (InputMismatchException exception) {
}
}
}
input.nextInt() won't consume anything not an int. It will throw an exception. You ignore the exception and try to consume an int. It's still not an int. Same exception. Infinite loop. Add another input.nextLine() in your catch block.
I have a try-catch that is meant to catch anything that is not an integer. When I enter a non integer (e.g. 5.6) it tells me only integers are allowed and lets me try again (as it should). But if I enter a non-integer again it doesn't say anything and will keep taking inputs, leaving output blank.
if (choicesObjects == b) {
System.out.println("TEST 2");
System.out.println("Object: Right triangle");
System.out.println("\nEnter length of Right triangle: ");
int lengthOfTriangle = 0;
try {
lengthOfTriangle = input.nextInt();
} catch(InputMismatchException e) {
System.out.println("\nError: user input must be an integer greater than 0.\n");
System.out.println("Object: Right triangle");
System.out.println("\nEnter length of Right triangle: ");
input.next();
}
//method stuff
}
The try/catch statement is not a loop. It will always be executed once.
Of course, if there is a loop inside the try block, that block will keep executing until terminated. But such a loop requires an explicit command like while or for to be used.
Apparently what happens when entering a non-integer value (e.g., 5.6), is that the nextInt() statement throws an Exception and goes to the catch block. A better explanation can be given if the full code of the method is provided.
For this you could define a function, something like this should work
private int getNextInt(Scanner input) {
boolean isInt = false;
int userInput;
while(!isInt) {
try {
userInput = Integer.valueOf(input.next());
isInt = true;
} catch(NumberFormatException e) {
// Do nothing with the exception
}
}
return userInput;
}
This should run until an input given was an int and then return said int
You can update your code to something like this -
Scanner in = new Scanner(System.in);
int num = 0;
while(true) {
try{
num = in.nextInt();
break;
}catch(Exception e){
//print statements
System.out.println("Try again");
}
}
System.out.println("Done");
something like this
Boolean check = true;
while (check) {
if choicesObjects == b {
enter code here` System.out.println("TEST 2");
System.out.println("Object: Right triangle");
System.out.println("\nEnter length of Right triangle: ");
int lengthOfTriangle = 0;
try {
lengthOfTriangle = input.nextInt();
} catch(InputMismatchException e) {
System.out.println("\nError: user input must be an integer greater than 0.\n");
check = false;
System.out.println("Object: Right triangle");System.out.println("\nEnter length of Right triangle:");
input.next();
}
//method stuff
}
}
`
I am starting to code in Java (never done so before), and I am having a headache with input validation.
I need that while a user inputs numbers from 0 to 1000, the while loops keeps getting executed. That works fine. The problem is I would like to check wether he inputs a number, and if he doesn't, the while loop should keep executing and waiting for the next input. So far my code only throws InputMismatchException when inputting something that is not a number and I can't see why.
Here is my code:
Scanner score = new Scanner(System.in);
int i = 0;
while (i < 1000000) {
System.out.print("Insert the new score: ");
if (score.hasNextInt()) {
i = score.nextInt();
if (i > 0) {
if (i < 200000) {
// do something
} else if (i < 500000) {
// do something
} else if (i < 700000) {
// do something
} else if (i < 100001) {
// do something
}
} else if (i < 0) {
// do something else
}
} else {
System.out.print("The score should be a number.");
i = score.nextInt();
}
}
else{
System.out.print("The score should be a number.");
i = score.nextInt(); //<---problem
}
Here you know that input was not a number so you shouldn't be trying to read it as int with nextInt(). So to consume invalid data use
next() which will return from scanner data as Sting which you can later ignore (you don't need to even store it in String variable)
or if you want to consume entire line use nextLine() (but be careful with this to avoid: Skipping nextLine() after using next(), nextInt() or other nextFoo() methods)
In your final else clause, you call score.nextInt() although you know that the next number isn't an int. That's why you get the exception. Just replace the else with this:
else {
System.out.print("The score should be a number.");
score.nextLine(); //This is the line you need to change
}
score.nextLine(); will consume the next line of input safely, and put you back in the loop.
You are receiving this error because you're telling Scanner to get an integer, even when the user does not type an integer. You need to instead accept all input (via a String) and do the validation yourself.
I've modded your code to take input as a String (Scanner#nextLine) and then attempt to update the score.
Scanner score = new Scanner(System.in);
int i = 0;
while (i < 1000000) {
System.out.print("Insert the new score: ");
if (score.hasNext()) {
final String input = score.nextLine();
try {
i = Integer.parseInt(input);
} catch (final Exception e) {
System.out.print("The score should be a number.");
continue;
}
}
if (i>0) {
if (i<200000) {
//do something
}
else if (i<500000) {
//do something
}
else if (i<700000) {
//do something
}
else if (i<100001) {
//do something
}
} else if (i<0) {
//do something else
}
}
Note the continue; statement will indefinitely ask the user for integer input until the user does, just as you requested in your question.
You may want to wrap while contents with try-catch block.
Scanner score = new Scanner(System.in);
int i = 0;
while (i < 1000000){
try{
System.out.print("Insert the new score: ");
if (score.hasNextInt()){
i = score.nextInt();
if (i>0){
if (i<200000){
do something
}
else if (i<500000){
do something
}
else if (i<700000){
do something
}
else if (i<100001){
do something
}
}else if (i<0){
do something else
}
}else{
System.out.print("The score should be a number.");
i = score.nextInt();
}
}catch(Exception e){}
}
You need to wrap your input statement inside a try/catch block and catch the InputMisMatchException. The InputMisMatchException happens because of using nextInt() in the Scanner which is expecting integer.
Scanner input = new Scanner(System.in);
int i = 0;
do {
try {
System.out.print("Enter integer ");
i = input.nextInt();
} catch (InputMismatchException e) {
//anything but integer gets caught here.
System.out.print("Please enter only integer.");
}
//necessary to take the cursor back to start of line, clear the buffer
input.nextLine();
} while (i < 1000000);
Above code example shows how to catch the InputMisMatchException.
I noticed that you have use input.hasNextInt() in your code, and all you need is to replace the following in the else block of your code.
i = score.nextInt()
with
score.nextLine();
As described in other answers, this sentence will clear the buffer waiting for next input. The exception is due to score.nextInt(), the replacement should fix it.
This was a difficult question to research, so please forgive me if this is a duplicate.
Basically, I have a while loop that'll only break if a code the user scans is an integer. I check this by trying Integer.parseInt(integer) and only breaks the loop if a NumberFormatException isn't thrown.
My problem, is that when the loop executes for the first time, the exception is thrown, without any user input.
Here's my code:
Scanner input = new Scanner(System.in);
while (true)
{
System.out.print("Please scan barcode: ");
int inCode = 0;
try
{
inCode = Integer.parseInt(input.next());
}
catch (NumberFormatException e)
{
System.out.println("Numbers only, please.");
}
if (inCode != 0) {
// Do Stuff
} else {
System.out.println("Code can't be zero!");
}
}
What should happen, is this:
Please scan barcode: // And here they enter the barcode
But instead this happens:
Please scan barcode: Numbers only, please.
Please scan barcode:
EDIT:
As per Bohemian's answer, I added the continue keyword to my code. That solves the issue, but only halfway. As per the request of the people who put my question on hold (With good reason, as I now see) I'll post a SSCCE for you guys. I'm going to remove the methods for interfacing with the database, though, only keeping the path that has the problem: creating a new account based on the code.
Scanner input = new Scanner(System.in);
while (true)
{
System.out.print("Please scan barcode: ");
int inCode = 0;
try
{
inCode = Integer.parseInt(input.next());
}
catch (NumberFormatException e)
{
System.out.println("Numbers only, please.");
continue;
}
if (true) // Here it checks if an account associated with the code entered exists in the database. Because I'm having issues when it creates a new account, I've made this true.
{
System.out.println("No account associated with that code! Create one?");
System.out.print("(yes/no): ");
String answer = input.next();
if (answer.equalsIgnoreCase("yes"))
{
System.out.println("Alright.");
System.out.print("Please enter a name: ");
String name = input.next();
System.out.print("Alright. Now I'll add that to the database... ");
// Here I add that to the database. Omitted.
System.out.println("Done! Please scan again to interface.");
}
else if (answer.equalsIgnoreCase("no"))
{
System.out.println("Okay then.");
}
else
{
System.out.println("Defaulting to no.");
}
}
}
// I still haven't written the code to interface with the account.
What happens now is, it says (in the first iteration)
Please scan barcode:
But, after going through the process of adding the account, it loops again and says:
Please scan barcode: Numbers only, please.
Please scan barcode:
EDIT:
Please note, everything is inside a while loop, so that when everything that the user has done is finished, it'll return to:
Please scan barcode:
I think what you want is this:
Scanner input = new Scanner(System.in);
while (true) {
System.out.print("Please scan barcode: ");
int inCode = 0;
try {
inCode = Integer.parseInt(input.next());
if (inCode != 0) {
// Do Stuff
break;
}
} catch (NumberFormatException e) {
System.out.println("Numbers only, please.");
}
}
The code you have could be structured better, which would both make it clearer what is happening and easier to track down problems. You only want to loop on the data input - so just loop on the data input:
int inCode = 0;
while (true) {
System.out.print("Please scan barcode: ");
try {
inCode = Integer.parseInt(input.next());
break;
} catch (NumberFormatException e) {
System.out.println("Numbers only, please.");
}
}
// Do stuff
You should consider using scanner.hasNextInt() and scanner.nextInt() rather than scanner.next() though. This will also avoid the need for using the exception like this. Normally using Exceptions to control program flow is a bad idea - really they should be used for handling exceptional circumstances. Integer.parseInt doesn't give you any alternatives, but scanner does.
After the edits, it's clear what the problem is: your while (true) loop doesn't have a break statement in it, so it will keep looping forever.
Personally, I'd suggest moving most of your code out of the loop, and only keeping the barcode-parsing code in it, e.g. like this:
int inCode;
while (true) {
System.out.print("Please scan barcode: ");
try {
inCode = Integer.parseInt(input.next());
if (inCode == 0) {
System.out.println("Code can't be zero!");
} else {
break; // we got a valid barcode! end the loop and move on...
}
} catch (NumberFormatException e) {
System.out.println("Numbers only, please.");
// no need for a "continue" here, since the loop will restart anyway
}
}
// rest of the code here...
or possibly even:
int inCode;
while (true) {
System.out.print("Please scan barcode: ");
try {
inCode = Integer.parseInt(input.next());
} catch (NumberFormatException e) {
System.out.println("Numbers only, please.");
continue;
}
if (inCode == 0) {
System.out.println("Code can't be zero!");
continue;
}
break; // we have a valid barcode! end the loop and move on...
}
// rest of the code here...
I would just continue the loop if there's bad input, then you don't need to test it later:
while (true) {
System.out.print("Please scan barcode: ");
int inCode = 0;
try {
inCode = Integer.parseInt(input.next());
} catch (NumberFormatException e) {
System.out.println("Numbers only, please.");
continue; // ADDED THIS LINE
}
// Do Stuff with inCode
}
Note that by your code testing for zero after the input, you preclude zero as valid input. This code allows any number, including zero. Small point, but there's no worries about edge cases.
You can try this
String in=null;
while (true) {
System.out.print("Please scan barcode: ");
int inCode = 0;
try {
in= input.next();
inCode=Integer.parseInt(in);
} catch (NumberFormatException e) {
System.out.println("Numbers only, please.");
}
if (inCode != 0) {
// Do Stuff
} else {
// Repeat loop
}
or you can directly read an integer through Scanner object instead of using Integer.parseInt() method.
int inCode=0;
while(true) {
System.out.print("Please scan barcode : ");
inCode=input.nextInt();
if(inCode!=0){ //do stuff }
else { //Repeat Loop }
}
I have been trying to stop the exceptions but I cannot figure out how.
I tried parseInt, java.util.NormalExceptionMismatch etc.
Does anyone have any insight how to fix this problem? Formatting is a bit off due to copy and paste.
do
{
System.out.print(
"How many integers shall we compare? (Enter a positive integer):");
select = intFind.nextInt();
if (!intFind.hasNextInt())
intFind.next();
{
// Display the following text in the event of an invalid input
System.out.println("Invalid input!");
}
}while(select < 0)
Other methods I have tried :
do
{
System.out.print(
"How many integers shall we compare? (Enter a positive integer):");
select = intFind.nextInt();
{
try{
select = intFind.nextInt();
}catch (java.util.InputMismatchException e)
{
// Display the following text in the event of an invalid input
System.out.println("Invalid input!");
return;
}
}
}while(select < 0)
It seems to me that you want to skip everything until you get an integer. This code here skips any input except an integer.
As long as there is no integer available (while (!in.hasNextInt())) discard the available input (in.next). When integer is available - read it (int num = in.nextInt();)
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (!in.hasNextInt()) {
in.next();
}
int num = in.nextInt();
System.out.println("Thank you for choosing " + num + " today.");
}
}
Quick sample of how to catch exceptions:
int exceptionSample()
{
int num = 0;
boolean done = false;
while(!done)
{
// prompt for input
// inputStr = read input
try {
num = Integer.parseInt(inputStr);
done = true;
}
catch(NumberFormatException ex) {
// Error msg
}
}
return num;
}
IMO, the best practice is to use nextLine() to get a String input, then parseInt it to get the integer. If unparsable, just complain back to the user and request re-entry.
Remember you may have to do a second nextLine() (discard the input) to clear up the buffer.