Unexpected return value from recursive function - java

I wrote a short piece of code with the purpose of setting an integer value. However, it does not seem to return the correct value. For example, for the following inputs I would expect it to work like so.
Please enter a positive integer value
-458
Please enter a positive valid integer
58
58
However, the actual output is the following.
Please enter a positive integer value
-458
Please enter a positive valid integer
58
-458
In this example why does it return -458 instead of 58?
import java.util.InputMismatchException;
import java.util.Scanner;
public class IncorectValueReturned {
public void run() {
System.out.println("Please enter a positive integer value");
System.out.println(setInt());
}
private int setInt() {
int i = -1;
Scanner sc = new Scanner(System.in);
try {
i = sc.nextInt();
if(i < 0) {
System.out.println("Please enter a positive valid integer");
setInt();
}
} catch(InputMismatchException iME) {
System.out.println("Please enter a positive valid integer");
setInt();
}
sc.close();
return i;
}
public static void main(String[] args) {
IncorectValueReturned iVR = new IncorectValueReturned();
iVR.run();
}
}

You never change the first i that was invalid, you need to recover the value of the recursive calls
i = setInt();
And of course, you should not redeclare this Scanner over and over.
Use a Instance variable instead.
Scanner sc = new Scanner(System.in);
private int setInt() {
int i = -1;
try {
i = sc.nextInt();
if(i < 0) {
System.out.println("Please enter a positive valid integer");
i = setInt();
}
} catch(InputMismatchException iME) {
//Clear the scanner of this value
sc.next();
System.out.println("Please enter a positive valid integer");
i = setInt();
}
return i;
}
And close the scanner when you are done with it.
Careful, a value that throws an exception will remain in the input, you need to read it, I used Scanner.next() to remove a bad input like a a value bigger than Integer.MAX_VALUE.

You didn't assign i the new value from SetInt().
if(i < 0) {
System.out.println("Please enter a positive valid integer");
i = setInt(); // <- HERE
}

Related

InputMismatchException help, how to override?

So, I've been stuck on this problem for a while and do not understand why my code is not working. I'm trying to teach myself Java and looking at conditionals and loops right now. So the program basically is just trying to read in an integer (int num), but if anything besides an int is entered have it ask for correct input and give a message describing what has been entered. I hope that makes sense. I'm not entirely sure if this is correct but I'm also very new to this and have been struggling to figure out what I'm missing.
Here's the code:
import java.util.Scanner;
public class LoopPrac{
public static void main (String [] args){
Scanner scan = new Scanner(System.in);
int num;
boolean bool = false;
System.out.println("Enter an Integer: ");
num = scan.nextInt();
scan.nextLine();
while(bool = false){
System.out.println("Enter an Integer: ");
num = scan.nextInt();
scan.nextLine();
if(scan.hasNextDouble()){
System.out.println("Error: Index is Double not Integer.");
}
if(scan.hasNext()){
System.out.println("Error: Index is String not Integer.");
}
if(scan.hasNextInt()){
bool = true;
}
}
System.out.println(num);
}
}
Your exception InputMismatchException is because you ask the scanner to scan the next integer scan.nextInt() but it found double or string or something else so it throws an exception that this input is not a integer.
So you can fix your code by first ask the scanner is next input is integer or not scan.hasNextInt(), it it int scan it, else check if it double or any type to print error message
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter an Integer: ");
if (scan.hasNextInt()) {
int Index = scan.nextInt();
System.out.println("Index = " + Index);
}
else if (scan.hasNextDouble()) {
System.out.println("Error: Index is Double not Integer.");
}
else {
System.out.println("Error: Index is not Integer.");
}
}

Asks user to enter values until an integer is entered

I am a noob in programming.
I wanted to write code for a prog which asks user to enter value until an integer is entered.
public class JavaApplication34 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int flag = 0;
while(flag == 0) {
int x = 0;
System.out.println("Enter an integer");
try {
x = sc.nextInt();
flag = 1;
} catch(Exception e) {
System.out.println("error");
}
System.out.println("Value "+ x);
}
}
}
I think the code is correct and it should ask me to enter the value again if i have entered anything other than an integer.
But when i run it , and say i enter xyz
it iterates infinite time without asking me to enter the value.
test run :
Enter an integer
xyz
error
Value 0
Enter an integer
error
Value 0
Enter an integer
error
Value 0
Enter an integer
error
Value 0
Enter an integer
error
Value 0
Enter an integer
error
Value 0
Enter an integer
error
Value 0
Enter an integer
error
Value 0
Enter an integer
error
Value 0
When a scanner throws an InputMismatchException, the scanner will not
pass the token that caused the exception.
Hence sc.nextInt() reads the same token again and throws the same exception again.
...
...
...
catch(Exception e){
System.out.println("error");
sc.next(); // <---- insert this to consume the invalid token
}
You can change your logic as shown below :
int flag = 0;
int x = 0;
String str="";
while (flag == 0) {
System.out.println("Enter an integer");
try {
str = sc.next();
x = Integer.parseInt(str);
flag = 1;
} catch (Exception e) {
System.out.println("Value " + str);
}
}
Here we have first read the input from Scanner and then we are trying to parse it as int, if the input is not an integer value then it will throw exception. In case of exception we are printing what user has enter. When user enters an integer then it will parsed successfully and value of flag will update to 1 and it will cause loop to exit.
In the error case, you need to clear out the string you've entered (for instance, via nextLine). Since it couldn't be returned by nextInt, it's still pending in the scanner. You also want to move your line outputting the value into the try, since you don't want to do it when you have an error.
Something along these lines:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int flag = 0;
while(flag == 0)
{
int x = 0;
System.out.println("Enter an integer");
try
{
x = sc.nextInt();
flag = 1;
System.out.println("Value "+ x);
}
catch (Exception e){
System.out.println("error");
if (sc.hasNextLine()) { // Probably unnecessary
sc.nextLine();
}
}
}
}
Side note: Java has boolean, there's no need to use int for flags. So:
boolean flag = false;
and
while (!flag) {
and
flag = true; // When you get a value
The answers to this question might help you
It makes use of Scanners .hasNextInt() function!

Exiting a while loop on java

I am trying to create a program where I use the getInt method to make sure that the user enters a positive number. I have this so far
public class Binary {
public static void main(String [ ] args) {
Scanner CONSOLE = new Scanner(System.in);
int decimal=getInt(CONSOLE, "Enter a positive integer: ");
}
public static int getInt(Scanner CONSOLE, String prompt) {
System.out.print(prompt);
while (!CONSOLE.hasNextInt()) {
CONSOLE.next();
System.out.println("Not an integer; try again.");
System.out.println(prompt);
}
int posInt=CONSOLE.nextInt();
while (posInt <= 0) {
System.out.println("Not a positive integer; try again.");
CONSOLE.next();
System.out.println(prompt);
}
return CONSOLE.nextInt();
}
}
The issue occurs that when the user does enter a positive number it still disregards the input and asks the user to enter a positive integer again. I guess I'm just not exiting the loop correctly but I'm not sure how.
Your problem is return CONSOLE.nextInt();
At the end of your method, you are calling CONSOLE.nextInt() which asks for input once more.
Return posInt, and you'll be fine.
Best of luck, HTH
Like the others said you can return posInt and you should be fine.
But i have some recommendations for your getInt method:
public static int getInt(Scanner CONSOLE, String prompt) {
//initialize vars
boolean valid = false;
int posInt = 0;
//while the input is not valid, loop over the evaluation
while(!valid){
System.out.print(prompt);
if (!CONSOLE.hasNextInt()) {
CONSOLE.next();
System.out.println("Not an integer; try again.");
//"continue" stops the loop here and starts it from the beginning
continue;
}
posInt=CONSOLE.nextInt();
if (posInt > 0) {
//valid = true will get us out of the loop
valid = true;
}else {
System.out.println("Not a positive integer; try again.");
}
}
return posInt;
}
This code will reevaluate the input from the beginning if the input before was invalid.
In your code if you enter a negative int you will be prompted to reenter a number.
But since you are already in the while (posInt <= 0) loop, it does not recheck if you actually enter a valid input.
The code i provided reevaluates the next input from the beginning until it is found valid.

How would i do input validation?

Tells the user if the number entered is even or even. I need help with the input validation. The validation i need do is that the user cannot entered anything but a number. Trying to do the validation without the try and catch method.
import java.util.Scanner;
public class oddoreven {
public static void main (String [] args) {
Scanner input = new Scanner (System.in);
//declaractions
int num;
//while loop
do{
System.out.println("PLease enter a number to see whether it is even or odd. To end tyype in -99.");
num = input.nextInt();
// input valid
}while(num != -99); // loop ends
// begins the method
public static void is_odd_or_even_number(int number){
int rem = number%2;
\
You can call Scanner.hasNextInt() to determine if the next input is an int (and consume anything else). Also, you might make an infinite loop and break when the input is -99 (or 99, your code tests for 99 but your prompt says -99). Finally, you should call your method. Something like,
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int num;
do {
System.out.println("Please enter a number to see whether it is "
+ "even or odd. To end type in -99.");
if (input.hasNextInt()) {
num = input.nextInt();
if (num != -99) { // <-- directions say -99.
is_odd_or_even_number(num);
} else {
break;
}
} else {
System.out.printf("%s is not a valid int.%n", input.nextLine());
}
} while (true);
}
You can use Scanner.nextLine() to get a string input. Then loop through the characters to make sure they are all digits. (assuming non-negative integers only)
string rawInput = input.nextLine();
boolean validInput = true;
for (char c : rawInput) {
if (!Character.isDigit(c)) {
validInput = false;
break;
}
}
if (validInput) {
int num == Integer.parseInt(rawInput);
// proceed as normal
}
else {
// invalid input, print out error message
}
You can use regex to check whether all the characters of string entered by user are digits or not,
num.matches("[0-9]+") // return true if all characters are digits
or
num.matches("^[0-9]*$") // return true if all characters are digits
but before that change your num = input.nextint() to num = nextLine() and make num as String. if you dont do this there is no need of validating user input as you are requiring.

A tiny issue with exception handling interactment - not the correct output

package test5555;
import java.util.InputMismatchException;
import java.util.Random;
import java.util.Scanner;
public class Test5555 {
private static int[] randomInteger;
public static void main(String[] args) {
boolean validInput = false;
randomInteger = new int[100];
Random rand = new Random();
for (int i = 0; i < randomInteger.length; i++)
randomInteger[i] = rand.nextInt();
int indexPosition = 0;
Scanner input = new Scanner(System.in); {
System.out.println("Please enter an integer for the array index position: ");
while(!validInput)
{
try
{
indexPosition = input.nextInt();
validInput = true;
System.out.println(randomInteger[indexPosition]);
} catch ( InputMismatchException | IndexOutOfBoundsException ex) {
System.out.print("Please enter a valid integer between 0 and 100 or type quit to exit: ");
String s = input.next();
if(s.equals("quit")){
System.exit(0);
System.out.println(randomInteger[indexPosition]);
}
}
}
}
}
}
The code runs perfectly except for two minor hiccups that I cannot solve. When you run it you get Please enter an integer for the array index position:If you type a number above 100 or a string such as bob then you get Please enter a valid integer between 0 and 100 or type quit to exit:which is perfect. But if you type quit then you get Please enter a valid integer between 0 and 100 or type quit to exit: BUILD SUCCESSFUL (total time: 2 minutes 2 seconds) so it quits it but it repeats the exception statement which I do not want.
When you type a number above 100 and receive the Please enter a valid integer between 0 and 100 or type quit to exit: if you then type a correct integer the program will just turn off and it will say BUILD SUCCESSFUL instead of retrieving the number for you from the array
Replace your while loop code with below,
String s = null;
while(!validInput)
{
try
{
if(s != null){
indexPosition = Integer.parseInt(s);
}
else{
indexPosition = input.nextInt();
}
System.out.println(randomInteger[indexPosition]);
validInput = true;
} catch ( InputMismatchException | NumberFormatException | IndexOutOfBoundsException ex ) {
System.out.println("Please enter a valid integer between 0 and 100 or type quit to exit: ");
input.nextLine();
s = input.next();
if(s.equals("quit")){
System.exit(0);
}
}
}
Please read this to get more idea on Scanner.
https://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html
In your case the problem is (As per doc)
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.
The behavior you describe in point 1 us not correct. If you type in a number and then quit it works "as expected"
If you type in a string such as "bob" your nextInt() fails with an InputMissmatchException which means your "input.next()" call in the catch clause will read "bob" and see it's not equal to "quit" and just go back to the loop and block and wait for an "int".
In point 2. You type an int and you get an exception...but you've set validInput to true already so you'll exit the loop. You need to set validInput after you print.
If I got your question correctly, I would implement little differently. Please check if it fulfills your requirement.
import java.util.Random;
import java.util.Scanner;
public class Test5555 {
private static int[] randomInteger;
public static void main(String[] args) {
randomInteger = new int[100];
Random rand = new Random();
int indexPosition;
for (int i = 0; i < randomInteger.length; i++)
randomInteger[i] = rand.nextInt();
Scanner input = new Scanner(System.in);
System.out.println("Please enter an integer for the array index position: ");
while(true) {
String strIndex = input.next();
if(strIndex.equals("quit")) break;
indexPosition = getIntVal(strIndex);
if(indexPosition < 0 || indexPosition >= randomInteger.length) {
System.out.print("Please enter a valid integer between 0 and "
+ randomInteger.length + " or type quit to exit: ");
continue;
}
System.out.println(randomInteger[indexPosition]);
break;
}
input.close();
}
protected static int getIntVal(String inputStr) {
int result = -1;
try {
result = Integer.parseInt(inputStr);
} catch(NumberFormatException e) {}
return result;
}
}
This part of your code is wrong
try
{
indexPosition = input.nextInt();
validInput = true;
System.out.println(randomInteger[indexPosition]);
} catch ( InputMismatchException | IndexOutOfBoundsException ex) {
You are saying that your indexPosition is right before to check it, the line
validInput = true;
Should be later of check if the array have that position.
Right code:
...
indexPosition = input.nextInt();
System.out.println(randomInteger[indexPosition]);
validInput = true;
....

Categories

Resources