Why do I have a never-ending do-while loop? - java

I have a non-working do-while loop. When I enter a String instead of an int, it should say "bla" and ask again to insert a number, but instead it sends the message text over and over again. What's wrong in this code?
boolean i = true;
do {
i = false;
try {
System.out.println("insert number");
int k = sc.nextInt();
}
catch(InputMismatchException e) {
System.out.println("test");
i = true;
}
} while ( i== true);

You need to do sc.nextLine() in the catch block to clear the erroneous input. The nextInt() call will leave the input in the buffer if it does not match the int pattern.

Related

Why does my error my exceptions handling cause an infinite loop?

I'm having trouble with my exception handling. The program runs fine if I input a number but create an infinite loop if a character is entered.
boolean ask= true;
while(ask)
{
ask = false;
try
{
System.out.println("What is the age?");
int age = input.nextInt();
setAge(age);
}catch(InputMismatchException e) {
System.out.println("Invalid input!");
ask = true;
}
}//end while
Try below code:
boolean ask= false;
while(!ask)
{
try
{
System.out.println("What is the age?");
int age = input.nextInt();//does not read the newline character in your input created by hitting "Enter,"
setAge(age);
ask = true;
}catch(InputMismatchException e) {
System.out.println("Invalid input!");
input.nextLine();//consumes the \n character
}
}//end while
Let's say you enter "abc"
Your call to input.nextInt() causes the scanner to look at the a and say "That's not an int, so I will throw an exception."
In the exception handler, you set ask to true so the loop repeats.
When the loop repeats, the scanner looks at that exact same a again, and it says "That's not an int, so I will throw an exception."
In the exception handler, you set ask to true so the loop repeats.
And so on....
That pesky a never gets consumed by the scanner.
From the source code of nextInt:
public int nextInt(int radix) {
// Check cached result
if ((typeCache != null) && (typeCache instanceof Integer)
&& this.radix == radix) {
int val = ((Integer)typeCache).intValue();
useTypeCache();
return val;
}
setRadix(radix);
clearCaches();
// Search for next int
try {
String s = next(integerPattern());
if (matcher.group(SIMPLE_GROUP_INDEX) == null)
s = processIntegerToken(s);
return Integer.parseInt(s, radix);
} catch (NumberFormatException nfe) {
position = matcher.start(); // don't skip bad token
throw new InputMismatchException(nfe.getMessage());
}
}
It uses Integer.parseInt(s, radix); to produce the result.
If call Integer.parseInt("s"); will result:
Exception in thread "main" java.lang.NumberFormatException: For input string: "s"

Try block in while loop doesnt execute on second iteration [duplicate]

This question already has answers here:
Error catching with try-catch and while loop [duplicate]
(1 answer)
How to handle infinite loop caused by invalid input (InputMismatchException) using Scanner
(5 answers)
Closed 7 years ago.
Hi I´m newbie in programming and I have this problem. I want to get input from user , using scanner. Program is supposed to try if input is valid, then call a function to do the job. Problem is I want program to repeat aking for input from user, if input is not valid. So I have try block in a while loop. The problem is on the first iteration of while loop everything is ok but when I insert invalid input and while loop is forced to iterate second time, try block is not executed and boolean which is condition of while loop is not set to false. So while loop runs for ever. Plz be kind.
public static void main(String args[]) {
Scanner scanner = new Scanner(System.in);
boolean isRunning = true;
int input;
while(isRunning) {
System.out.println("insert a number:");
try {
input = scanner.nextInt();
inputToString(input);
isRunning = false;
} catch(InputMismatchException e) {
System.out.println("input musi byt cele cislo");
isRunning = true;
}
}
}
public static void inputToString(int input) {
System.out.println(input);
}
You need to consume invalid number from Scanner before asking for new one since nextInt didn't consume it, but thrown exception.
} catch (InputMismatchException e) {
System.out.println("input musi byt cele cislo");
scanner.next();//consume
isRunning = true;
}
But you should not use exceptions and try-catch sections as main part of control logic. Scanner provides hasNextInt() method to test if user provided valid input. So your code should be like
System.out.print("give me the money:");//ask user of integer
while(!scanner.hasNextInt()){//test is provided value is valid integer
String token = scanner.next();//consume incorrect value
//inform that value is not correct and ask for new one
System.our.println(token + " is not considered as valid number");
System.our.print("please try again:");
}
//here we know that user provided valid integer
value = scanner.nextInt();
The problem with your approach is that when the input is not a valid int you leave it in the input buffer. The next loop will see exactly the same input, and it would repeat exactly the same actions (throw, catch, continue with the loop).
What you should do is to drop the incorrect input from the scanner when you see that it does not match what you expect. You could do it in your catch block, like this:
try {
input = scanner.nextInt();
inputToString(input);
isRunning = false;
} catch(InputMismatchException e) {
System.out.println("input musi byt cele cislo");
isRunning = true;
scanner.nextLine(); // Drop input from the scanner's buffer
}
A better approach would be to not rely on try/catch in the scanning code at all. Scanner provides a convenient way for you to avoid exceptions: calling hasNextInt before you call nextInt lets you find out ahead of time if the exception would be thrown or not, and clean the wrong data from the buffer:
while(isRunning) {
System.out.println("insert a number:");
if (scanner.hasNextInt()) {
input = scanner.nextInt();
inputToString(input);
isRunning = false;
} else {
System.out.println("input musi byt cele cislo");
isRunning = true;
scanner.nextLine(); // Drop input from the scanner's buffer
}
}
you should reinitialize Scanner reference before scanning input
public static void main(String args[]) {
Scanner scanner = null;
boolean isRunning = true;
int input;
while (isRunning) {
System.out.println("insert a number:");
try {
scanner = new Scanner(System.in);
input = scanner.nextInt();
inputToString(input);
isRunning = false;
} catch (InputMismatchException e) {
System.out.println("input musi byt cele cislo");
isRunning = true;
}
}
}
public static void inputToString(int input) {
System.out.println(input);
}
this works

If user inserts character other than Integer, the program should give him another chance to write an integer

Ok, im trying to stop a user from enterring values other than Integers and smaller than 3 (first case). So far i have this code and the problem is, i cant make it stop, until the user enters correct values. i want to stup it and make him insert an integer into variable n and then can continue to add a value into variable a . how should i do this?
EDIT : new code
public class mnohouholnik {
public double a;
public int n;
public void main() {
Scanner sc = new Scanner(System.in);
boolean error = false;
while ( ! error && n<3 ) { //you cant have a polygon which has only two angles
try
{
System.out.println("Enter the number of angles in polygon");
n = sc.nextInt();
error = true;
}
catch(InputMismatchException e )
{
System.out.println("Wrong value, try again");
sc.nextLine();
}
try
{
System.out.println("Insert the length of the side :");
a = sc.nextDouble();
error = true;
}
catch(InputMismatchException e )
{
System.out.println("Wrong value, try again");
sc.nextLine();
}
}
}
}
Something like this:
boolean validInput = false;
while ( ! validInput ) {
try
{
System.out.println("Please insert a number of angles in polygon:");
n = sc.nextInt();
validInput = true;
}
catch(InputMismatchException exception )
{
System.out.println("Thats not an integer");
}
}
First, it assumes the input is not valid. It will repeat the input process while the input is not valid. The flag that tells it to stop is changed only after the sc.nextInt() call. If that call throws an exception, control will pass to the catch clause and validInput will not be changed. If it works OK and doesn't throw an exception, validInput = true will be executed, so the next time the while checks its condition, it will stop.
Try something like:
boolean valid = false;
while(valid == false){
//input code here
//if statement changing 'valid' to true, if the input is valid
}

Checking if an input is an Integer using exceptions - Java

My method must request input from the user, check if it is an integer, and if it is return that integer. I attempted this using a try catch and the InputMismatchException.
I am running into an issue when it loops, if I input a non integer, it continuously spits out "Invalid input" "Enter an integer: " instead of actually asking for one.
public int getInteger(){
Scanner i = new Scanner(System.in);
int value = 0;
for(boolean test = false; test == false;){
try{
System.out.println("Enter an integer: ");
value = i.nextInt();
test = true;
return value;
}
catch(InputMismatchException e){System.out.println("Invalid input");}
}
return value;
}
You need a i.nextLine(); at the end of the loop.
catch(InputMismatchException e){System.out.println("Invalid input");}
i.nextLine();
}
What that does is reads the new line character, left unread by i.nextInt(), from the input stream. It's also the reason your i.nextInt() keeps tripping on the subsequent calls.
I suggest you call hasNextInt() before nextInt() instead of trying to catch the Exception. Something like,
public int getInteger() {
Scanner scan = new Scanner(System.in);
while (scan.hasNextLine()) {
if (scan.hasNextInt()) {
return scan.nextInt();
} else {
System.out.printf("%s is not an int%n", scan.nextLine());
}
}
return -1;
}

Scanner keeps skipping input whist using nextInt() and loops

I am using a while loop to make sure that the value entered to a scanner object is an integer as such:
while (!capacityCheck) {
try {
System.out.println("Capacity");
capacity = scan.nextInt();
capacityCheck = true;
} catch (InputMismatchException e) {
System.out.println("Capacity must be an integer");
}
}
however, if the user does not enter an integer, when it should go back and take another input it just repeatedly prints "Capacity" followed by the output in the catch without asking for more input. How do I stop this?
scan.nextLine();
Put this piece of code inside your catch block, to consume the non integer character along with the new line character which is stays in the buffer(hence, infinitely printing the catch sysout), in the case where you've given a wrong input.
Ofcourse, there are other cleaner ways to achieve what you want, but I guess that will require some refactoring in your code.
Use the following:
while (!capacityCheck) {
System.out.println("Capacity");
String input = scan.nextLine();
try {
capacity = Integer.parseInt(input );
capacityCheck = true;
} catch (NumberFormatException e) {
System.out.println("Capacity must be an integer");
}
}
Try this :
while (!capacityCheck) {
try {
System.out.println("Capacity");
capacity = scan.nextInt();
capacityCheck = true;
} catch (InputMismatchException e) {
System.out.println("Capacity must be an integer");
scan.nextLine();
}
}
Try putting this at the end of the loop -
scan.nextLine();
Or better to put it in the catch block.
while (!capacityCheck) {
try {
System.out.println("Capacity");
capacity = scan.nextInt();
capacityCheck = true;
} catch (InputMismatchException e) {
System.out.println("Capacity must be an integer");
scan.nextLine();
}
}
I see no need for a try/catch or capacityCheck as we have access to the method hasNextInt() - which checks if the next token is an int. For instance this should do what you want:
while (!scan.hasNextInt()) { //as long as the next is not a int - say you need to input an int and move forward to the next token.
System.out.println("Capacity must be an integer");
scan.next();
}
capacity = scan.nextInt(); //scan.hasNextInt() returned true in the while-clause so this will be valid.

Categories

Resources