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 }
}
Related
I am just trying to get code to work where the code asks again for an answer, if text or a symbol is entered, instead of a required integer:
import java.util.Scanner;
class timecalc {
int hrs = 0;
int min = 0;
static int hourflag = 0;
static int minflag = 0;
Scanner sc = new Scanner(System.in);
public int getHours() {
try {
hourflag = hourflag + 1;
if (hourflag > 1) {
System.out.println("Invalid month Please enter hours again:");
}
System.out.println("Enter month:");
return hrs = sc.nextInt();
} catch (InputMisMAtchException e) {
System.out.println("entered invalid input " + e);
}
}
Have reviewed answers already given but cant get a workable solution
Any ideas?
I won't give you the entire code, but just a hint or psuedo-code. As an exercise you can implement it as per your requirement.
System.out.println("Enter month:");
while (true) {
try {
int min = sc.nextInt();
break;
} catch (InputMismatchException ex) {
System.err.println("Invalid input, please enter again");
sc.nextLine(); // <----- advance the scanner
}
}
Here the logic is to loop until we get the right input. If it is an invalid input, the loop never breaks.
Also as a side-note, I would recommend you to create just one method to fetch correct inputs and call it respectively from other methods. Rather than duplicating this logic everywhere.
The algorithm should take in 3 integers to an ArrayList. If the input is not an integer, then there should be a prompt. When I execute my code the catch clause is executed, but the program runs into a infinite loop. Could someone guide me into the right direction, I appreciate the help. :-D
package chapter_08;
import java.util.Scanner;
import java.util.List;
import java.util.ArrayList;
public class IntegerList {
static List<Integer> numbers = new ArrayList<Integer>();
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int counter = 1;
int inputNum;
do {
System.out.print("Type " + counter + " integer: " );
try {
inputNum = input.nextInt();
numbers.add(inputNum);
counter += 1;
}
catch (Exception exc) {
System.out.println("invalid number");
}
} while (!(numbers.size() == 3));
}
}
That is because when the next int is read using nextInt() and it fails, the Scanner still contains the typed contents. Then, when re-entering the do-while loop, input.nextInt() tries to parse it again with the same contents.
You need to 'flush' the Scanner contents with nextLine():
catch (Exception exc) {
input.nextLine();
System.out.println("invalid number");
}
Notes:
You can remove the counter variable, because you're not using it. Otherwise, you could replace counter += 1 by counter++.
You can replace while (!(numbers.size() == 3)) with while (numbers.size() != 3), or even better: while (numbers.size() < 3).
When catching exceptions, you should be as specific as possible, unless you have a very good reason to do otherwise. Exception should be replaced by InputMismatchException in your case.
If inputNum = input.nextInt(); cannot be fit into an int and a InputMismatchException is raised, the input of the Scanner is not consumed.
So after the catch, it loops and it goes again here :
inputNum = input.nextInt();
with exactly the same content in the input.
So you should execute input.nextLine(); in the catch statement to discard the current input and allow a new input from the user.
Besides it makes more sense to catch InputMismatchException rather than Exception as other exception with no relation with a mismatch could occur and it would not be useful to display to the user "invalid number " if it is not the issue :
catch (InputMismatchException e){
System.out.println("invalid number ");
input.nextLine();
}
You should to use a break; in your catch(){} like so :
try {
inputNum = input.nextInt();
numbers.add(inputNum);
counter += 1;
} catch (Exception e) {
System.out.println("invalid number ");
break;
}
So if one input is not correct break your loop.
try changing
inputNum = input.nextInt();
to
String inputText=input.next();
inputNum = Integer.valueOf(inputText);
it works perfectly well.
You need to move the scanner to the next line. Add this line of code below the error message in the catch section.
input.nextLine();
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.
The code below asks the user how many racers he/she would like.
while (true) { // loops forever until break
try { // checks code for exceptions
System.out.println("How many racers should" + " participate in the race?");
amountRacers = in.nextInt();
break; // if no exceptions breaks out of loop
}
catch (InputMismatchException e) { // if an exception appears prints message below
System.err.println("Please enter a number! " + e.getMessage());
continue; // continues to loop if exception is found
}
}
If a number is entered at amoutnRacers = in.nextInt(); the code breaks out of the loop and the rest of the program runs fine; however, when I enter something such as "awredsf" it should catch that exception, which it does. Instead of prompting the user again it loops continuously, which to me does not make sense.
The program prints like this when looping continuously:
How many racers should participate in the race?
How many racers should participate in the race?
How many racers should participate in the race?
How many racers should participate in the race?
How many racers should participate in the race?
How many racers should participate in the race?
How many racers should participate in the race?Please enter a number! null
Please enter a number! null
Please enter a number! null
Please enter a number! null
Please enter a number! null
Please enter a number! null
Please enter a number! null
...
I do not understand what is going on amountRacers = in.nextInt(); so why is the user not able to enter a number?
Just add input.next() once you catch InputMismatchException.
catch (InputMismatchException e) { //if an exception appears prints message below
System.err.println("Please enter a number! " + e.getMessage());
input.next(); // clear scanner wrong input
continue; // continues to loop if exception is found
}
You need to clear the wrong input, which scanner automatically does not.
Today i solved this problem :-) This is my code. I think that i help
public int choice () throws Exception{
Scanner read = new Scanner(System.in));
System.out.println("Choose the option from the upper list");
int auxiliaryChoiceMenu = 5;
int auxiliaryVariable = -1;
boolean auxiliaryBoolean = false;
while (!auxiliaryBoolean) {
try {
auxiliaryVariable = read.nextInt();
read.nextLine();
} catch (Exception e) {
System.out.println("incorrect data, try again"+e);
read.nextLine();
continue;
}
if (auxiliaryVariable<0 || auxiliaryVariable>auxiliaryChoiceMenu){
System.out.println("incorrect data, try again");
} else {
auxiliaryBoolean = true;
}
choiceMenu = auxiliaryVariable;
}
return choiceMenu;
//choicemenu is a external variable
}
You may need to create a Scanner class for getting standard input streamed from the keyboard. You should have a statement somewhere in your code that creates an instance of a Scanner class like: Scanner in = new Scanner(System.in);
so the " in " variable in your statement: amountRacers = in.nextInt(); waits and scans for entered input from the keyboard and stores it.
Why use a loop with a try and catch?
My advice would be to always use a try and catch with either a while or do while loop, so you can ask the user to repeat his/her input. It also depends which loop you already use and/or on how your code is structured.
For example if you already have a do while loop then I would advice you to simply adjust/modify your existing loop.
I will post some examples on how you can use a try and catch with a loop to repeat the input after a user has provided a wrong one.
See examples below:
Example 1
Scanner input = new Scanner(System.in);
int exampleInput = 0;
do {
try {
System.out.print("\nEnter an integer from 1 to 25: ");
exampleInput = input.nextInt();
}
catch (InputMismatchException e) { //if an exception appears prints message below
System.err.println("Wrong input! Enter an integer from 1 to 25");
input.next(); // Clear scanner buffer of wrong input
}
} while (exampleInput < 1 || exampleInput > 25);
System.out.println("Print exampleInput: " + exampleInput);
Example 2
Scanner input = new Scanner(System.in);
int exampleInput; // Here you don't need to initialize this variable because you don't need it as a condition for the loop.
boolean isDone = false;
do {
try {
System.out.print("\nEnter an integer: ");
exampleInput = input.nextInt();
isDone = true;
}
catch (InputMismatchException e) { //if an exception appears prints message below
System.err.println("Wrong input! Enter an integer");
input.next(); // Clear scanner buffer of wrong input
}
} while (!isDone);
System.out.println("Print exampleInput: " + exampleInput);
Example 3
Scanner input = new Scanner(System.in);
int exampleInput; // Here you don't need to initialize this variable because you don't need it as a condition for the loop.
boolean isDoneLoop2 = false;
while (!isDoneLoop2) {
try {
System.out.print("\nEnter an integer: ");
exampleInput = input.nextInt();
isDoneLoop2 = true;
}
catch (InputMismatchException e) { //if an exception appears prints message below
System.err.println("Wrong input! Enter an integer");
input.next(); // Clear scanner buffer of wrong input
}
}
System.out.println("Print exampleInput: " + exampleInput);
This works for me.
while (true) {
try {
System.out.print("Ingrese la cantidad de puestos de atenciĆ³n: ");
int puestos = Integer.parseInt(scn.nextLine());
break;
}
catch (NumberFormatException e) {
System.out.println("Ingrese un valor correcto");
scn.reset();
continue;
}
}
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.