Java IOException InfiniteLoop - java

I have this method and I want to check for user input. If it is a number but greater than 9 and lees than 1 or Char / String I want to throw an Exception. With the numbers it works but when I want to check for char/Strings it goes in infinite loop.
private static Scanner in = new Scanner(System.in);
public static int getPlayerPositionInput(String message) {
System.out.println(message);
while(true) {
System.out.println("1");
try {
if(in.hasNextInt()){
int i = in.nextInt();
if(i<1 || i>9 ) throw new IOException();
return i;
} else throw new IOException();
} catch(Exception e) {
System.out.println("The number has to be greater than 0 and less than 10");
}
}
}
I was thinking about using ASCII table, would it be a good idea ?

If you enter a String then if(in.hasNextInt()){ will always be false and hence no input will be possible.
Try using hasNext and nextLine

The problem is, that after you submit the non-numeric string, hasNextInt() returns false. But scince you do not discard the wrong input, it will return false the next time it is called, too.
Try this:
while (true) {
System.out.println("1");
try {
if (in.hasNext()) {
if (in.hasNextInt()) {
int i = in.nextInt();
if (i < 1 || i > 9) {
throw new IOException();
}
return;
} else {
in.next(); // discard the input
throw new IOException();
}
}
} catch (IOException e) {
System.out.println("The number has to be greater than 0 and less than 10");
}
}

Its because you are catching the exception and going for next loop.
Exception is Super Class to IOException. Go through below documentation.
http://docs.oracle.com/javase/7/docs/api/java/io/IOException.html
Your exception catching logic needs to be refactored.

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"

JAVA: Problems with Exception-Handling? Program only catches Exception once

I'm attempting to create a program where the user enters a five-digit zip code from 00000 to 99999 and if the user enters a number out of that range or non-numeric values, it should throw an exception and give the user a chance to keep trying until they enter 5 numeric values.
My program only seems to catch the first instance of it, and afterwards it simply prints out the 2nd thing the user enters even if it doesn't fit the requirements.
I've just been stumped, and I'm not sure how I can use a while loop with my code, though I believe that's what I may need maybe?
I'm a beginner at this and any help would be appreciated!
import java.util.InputMismatchException;
import java.util.Scanner;
public class xzip_code {
public static void main(String[] args)
{
try
{
Bounds(Program());
}
catch(IllegalArgumentException ex)
{
System.out.println("Enter 5 Digits");
Program();
}
catch(InputMismatchException ex)
{
System.out.println("Enter Numbers");
Program();
}
}
public static void Bounds(String answer)
{
int length = answer.length();
if(length<5 || length>5)
{
throw new IllegalArgumentException("Enter 5 Digits");
}
char a = answer.charAt(0);
char b = answer.charAt(1);
char c = answer.charAt(2);
char d = answer.charAt(3);
char e = answer.charAt(4);
int f = a;
int g = b;
int h = c;
int i = d;
int j = e;
if(f>58 || g>58 || h>58|| i>58||j>58)
{
throw new InputMismatchException("Enter Numbers");
}
}
public static String Program()
{
Scanner userInput = new Scanner(System.in);
String x = userInput.next();
System.out.println(x);
return x;
}
}
Your method Bounds() does the validation work.
Currently, in your catch block you are just calling Program(). Instead you need to call the Bounds() and pass parameter Program() to it.
The below code will loop until there is no exception (successful try block execution).
boolean flag = true;
while(flag) {
try {
Bounds(Program());
flag = false;
} catch(IllegalArgumentException ex) {
System.out.println("Enter 5 Digits");
}
catch(InputMismatchException ex) {
System.out.println("Enter Numbers");
}
}
You also need to check if user has entered only numbers.
ASCII value of 0 -> 48 and 9 -> 57. Therefore, your check of > 58 makes no sense. It should check within the range.
You can simple use if (Character.isLetter(answer.charAt(index))) to check for individual digits (which is tedious).
Instead, just convert the String to Integer and check if it successfully gets converted otherwise throw error.
try {
Integer.parseInt(answer);
} catch (NumberFormatException e) {
throw new InputMismatchException("Enter Numbers");
}
You need to call Bounds(Program()); untill your program throws no error.
For that I created while loop that verifies if boolean isError is true.
To check if entered char is digit you can use Character.isDigit method.
See correct code:
package com.stackoverflow.main;
import java.util.InputMismatchException;
import java.util.Scanner;
public class xzip_code {
public static void main(String[] args) {
System.out.println("Enter 5 Digits");
boolean isError = true;
while (isError) {
try {
Bounds(Program());
} catch (IllegalArgumentException ex) {
System.out.println("Enter 5 Digits");
continue;
} catch (InputMismatchException ex) {
System.out.println("Enter Numbers");
continue;
}
isError = false;
}
}
public static void Bounds(String answer) {
int length = answer.length();
if (length < 5 || length > 5) {
throw new IllegalArgumentException("Enter 5 Digits");
}
char a = answer.charAt(0);
char b = answer.charAt(1);
char c = answer.charAt(2);
char d = answer.charAt(3);
char e = answer.charAt(4);
if (!(Character.isDigit(a) && Character.isDigit(b) && Character.isDigit(c) && Character.isDigit(d)
&& Character.isDigit(e))) {
throw new InputMismatchException("Enter Numbers");
}
}
public static String Program() {
Scanner userInput = new Scanner(System.in);
String x = userInput.next();
System.out.println(x);
return x;
}
}
Prints:
Enter 5 Digits
ewewdsddd
ewewdsddd
Enter 5 Digits
dffdffg
dffdffg
Enter 5 Digits
443446665
443446665
Enter 5 Digits
4444q
4444q
Enter Numbers
33333
33333
You need to make your catch a recursive call. The way you wrote it, it is caught, tries again, then ends.
Try to do it like this.
void foo() {
try {
bar();
} catch (Exception e) {
// try again
foo();
}
}
It also may be a good idea to keep track of how many times you retry. This could easily cause a StackOverflowError if you get it wrong too many times. I want to say the number is about 8 or 9 thousand.
Another option would be to use a loop.
void foo() {
boolean success = false;
while(!success) {
success = tryFoo();
}
}
boolean tryFoo() {
try {
bar();
return true; // true for success
} catch (Exception e) {
return false; // false for failed
}
}

need to output error if anything EXCEPT 1 or 2 is input by user

So it looks like it allows me to input all ints, and when i do a string or anything else it does give me error, but how do I go about making it so its ONLY 1 and/or 2 accept and 3,4,5....(every other number) are not excepted...
Code below
public static void main(String[] args){
System.out.println("Please enter 1 to add or 2 to multiply. "); // ask user to input 1 or 2
Scanner in = new Scanner(System.in);
try {
int add = in.nextInt(); // add for 1
int multiply = in.nextInt(); // multiply for 2
}
catch (Exception e) {
System.out.println("Operation failed. You need to enter 1 or 2.");
}
}
Exceptions here would be overkill IMO. Just using if else clauses would work equally well. Like this:
if(input == 1) {
// add
}
else if(input == 2) {
// multiply
}
else {
System.out.println("Operation failed. You need to enter 1 or 2.");
}
Also if you want the program to keep prompting you can just wrap it in a loop. Here is a small example using a boolean sentinel to keep the loop going. This is one of many ways to implement this task.
public static void main(String[] args) {
System.out.println("Please enter 1 to add or 2 to multiply. "); // ask user to input 1 or 2
Scanner in = new Scanner(System.in);
boolean inputNotValid = true;
while(inputNotValid){
int input = in.nextInt();
if(input == 1) {
inputNotValid = false;
//add
System.out.println("adding");
}
else if(input == 2) {
inputNotValid = false;
//multiply
System.out.println("multiplying");
}
else {
System.out.println("Operation failed. You need to enter 1 or 2. Try again");
}
}
}
Replace:
int add = in.nextInt(); // add for 1
int multiply = in.nextInt(); // multiply for 2
with:
int value = in.nextInt();
if(value == 1) // do add
if(value == 2) // do multiply
// else case = error
The whole program would become:
public static void main(String[] args)
{
System.out.println("Please enter 1 to add or 2 to multiply. ");
Scanner in = new Scanner(System.in);
try
{
int value = in.nextInt();
if (value == 1)
{
System.out.println("add");
// do add
}
else if (value == 2)
{
System.out.println("mult");
// do multiply
}
else
{
// error
System.out.println("Operation failed. You need to enter 1 or 2.");
}
}
catch (Exception e)
{
System.out.println("Read operation failed. This should not happen!");
}
}
The javadoc for nextInt() says:
Scans the next token of the input as an int.
An invocation of this method of the form nextInt() behaves in exactly the same way as the invocation nextInt(radix), where radix is the default radix of this scanner.
Returns:
the int scanned from the input
Throws:
InputMismatchException - if the next token does not match the Integer regular expression, or is out of range
NoSuchElementException - if input is exhausted
IllegalStateException - if this scanner is closed
You still can catch the InputMismatchException, the NoSuchElementException and the IllegalStateException, since in.nextInt() can throw them. You could also catch Exception (the only superclass of all three exceptions) instead.
Since Exception is an unchecked Exception, you can also remove the try-catch. Beware though, that an error in the Input will then exit the whole program.

Arithmetic in java

I have the following homework problem:
Write an application integer on that
reads an integer and determines and
prints whether it is odd or even.
Use the Scanner class for reading input.
Store that input into an integer. Check if input is really a valid integer. Otherwise, throw an exception.
Afterwards, use the modulo operator to check if it's odd or even.
Use System.out.println to print if it's odd or even.
public static void main(String[] args) {
System.out.println("Enter number");
Scanner sc = new Scanner(System.in);
try {
int i = sc.nextInt();
if (Math.abs(i) / i == 1) {
if ((Math.abs(i) % 2) == 0) {
System.out.println("Even");
} else {
System.out.println("Odd");
}
}
} catch (Exception ex) {
System.out.println("Exception " + ex.toString());
}
}

Infinite While Loop in Java

Hey there! I'm trying to do some data input validation but I haven't been able to figure it out. I'm getting an infinite while loop in when I try to validate if the first character entered is a letter. . . .
Thanks for your help!
public class methods
{
public static void main(String args[]) throws IOException
{
String input ="";
int qoh=0;
boolean error=true;
Scanner keyboard = new Scanner (System.in);
//while (error)
//{
//error=true;
while (error==true)
{
System.out.print("\nEnter Quantity on Hand: ");
input = keyboard.nextLine();
if (input.length() <1)
{
System.out.println("\n**ERROR06** - Quantity on hand must be between 0 and 500");
error=true;
System.out.println(qoh);
System.out.println(input);
}
else
{
error=false;
}
}
error = true;
while (error==true)
{
if (Character.isLetter(input.charAt(0)))
{
System.out.println("\n**ERROR06** - Quantity on hand must be between 0 and 500");
error=true;
System.out.println(qoh);
System.out.println(input);
}
else
{
qoh = Integer.parseInt(input);
error=false;
}
}
}
}
You don't have an input = keyboard.nextLine(); in your second while loop.
You could refactor your code to only ask for new input when there is an error. So right after the sysout of 'ERROR...'
Extra:
I would actually do this different. The 'error = true' at the beginning is a bit confusing, because there might not be an error.
You could for example write a method called tryProcessLine, which reads the input and returns true if ok and false if there was an error, and than just do something like while(!tryProcessLine()){ }
Working example below:
import java.io.IOException;
import java.util.Scanner;
public class Methods {
private static int qoh;
public static void main(String args[]) throws IOException {
while (!tryProcessLine()) {
System.out.println("error... Trying again");
}
System.out.println("succeeded! Result: " + qoh);
}
public static boolean tryProcessLine() {
String input = "";
Scanner keyboard = new Scanner(System.in);
System.out.print("\nEnter Quantity on Hand: ");
input = keyboard.nextLine();
try {
qoh = Integer.valueOf(input);
if (qoh < 0 || qoh > 500) {
System.out.println("\n**ERROR06** - Quantity on hand must be between 0 and 500");
return false;
} else {
return true;
}
} catch (NumberFormatException e) {
System.out.println("\n**ERROR06** - Quantity on hand must be numeric");
return false;
}
}
}
The problem is in this section:
while (error==true)
{
if (Character.isLetter(input.charAt(0)))
{
System.out.println("\n**ERROR06** - Quantity on hand must be between 0 and 500");
error=true;
System.out.println(qoh);
System.out.println(input);
}
else
{
qoh = Integer.parseInt(input);
error=false;
}
}
Once you have a letter in the first position, this loop can never terminate. It checks whether a letter is in the first position (it is), prints it, and repeats. Try changing to:
while (error==true)
{
if (Character.isLetter(input.charAt(0)))
{
System.out.println("\n**ERROR06** - Quantity on hand must be between 0 and 500");
error=false;
...
Also, a couple of other things:
while (error == true) can be shortened to while(error).
Also, Integer.parseInt will throw a NumberFormatException if the input is not an integer - you need to catch and handle this.
Also, why do you need the second loop at all? It seems like it is only supposed to validate the input - if so, you can move this logic into the first loop and eliminate the second one. Only use loops for things that should happen repeatedly (like the user entering input data). There is no need to check the same input repeatedly.
The infinite loop occurs because the second while loop is repeatedly checking whether the first character in the String (input.charAt(0)) is a letter. Assuming that the result from this check is true the loop will never terminate.
Your code could be simplified to something like:
Integer qty = null;
while (scanner.hasNext() && qty == null) {
String line = scanner.next();
try {
qty = Integer.parseInt(line);
} catch(NumberFormatException ex) {
System.err.println("Warning: Ignored non-integer value: " + line);
}
}
if (qty == null) {
System.err.println("Warning: No quantity specified.");
}
If it is a character, you're allowing error to still = true, which is causing that loop to continue forever, you're not ever going back to the beginning and reading another line.
Here is some code that does what you want and is structured a little better.
public class ScanInfo {
Scanner keyboard = new Scanner(System.in);
public ScanInfo(){
String line = getLineFromConsole();
while(null != line && !"quit".equals(line)){
if(isValidInput(line)){
int validNumber = Integer.parseInt(line);
System.out.println("I recieved valid input: "+validNumber);
}else{
System.out.println("\n**ERROR06** - Quantity on hand must be between 0 and 500");
}
line = getLineFromConsole();
}
}
private boolean isValidInput(String line){
//basic sanity
if(null == line || line.length() < 1){
return false;
}
try {
int number = Integer.parseInt(line);
return (number >= 0 && number <= 500);
} catch (NumberFormatException e) {
return false;
}
}
public static void main(String[] args) {
new ScanInfo();
}
public String getLineFromConsole(){
System.out.print("\nEnter Quantity on Hand: ");
return keyboard.nextLine();
}
}

Categories

Resources