Asks user to enter values until an integer is entered - java

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!

Related

Unexpected return value from recursive function

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
}

Do while goes infinite with try catch

I have a problem when trying to execute try-catch statement inside do while loop.I ask user to first enter letter and then a number and if he enters number correctly the program ends.If he enters letter instead of number the program should say "An error occurred please enter number " and ask user to enter number again but every time i type letter instead of number the program goes into an infinite loop and won't allow me to enter new value.
And just goes
"An error occurred you must enter number"
"Please enter number".
public class OmaBrisem {
public static void main(String[] args) {
Scanner tastatura = new Scanner(System.in);
boolean b = true;
int a = 0;
String r = "";
System.out.println("Please enter a letter");
r = tastatura.next();
do {
try {
System.out.println("Please enter numerical value");
a = tastatura.nextInt();
b = true;
} catch (Exception e) {
System.out.println("An error occured you must enter number");
b = false;
}
} while (!b);
}
}
Here's your problem. If the user enters a non-number where you expect a number, your nextInt() will raise an exception but it will not remove the letter from the input stream!
That means when you loop back to get the number again, the letter will still be there and your nextInt() will once again raise an exception. And so on, ad infinitum (or at least until the heat death of the universe, or the machine finally breaks down, whichever comes first).
One way to fix this would be to actually read/skip the next character when nextInt() fails so that it's removed from the input stream. You could basically do this with Scanner.findInLine(".") until Scanner.hasNextInt() returns true.
The following code shows one way to do this:
import java.util.Scanner;
public class MyTestProg {
public static void main(String [] args) {
Scanner inputScanner = new Scanner(System.in);
System.out.print("Enter letter, number: ");
// Get character, handling newlines as needed
String str = inputScanner.findInLine(".");
while (str == null) {
str = inputScanner.nextLine();
str = inputScanner.findInLine(".");
}
// Skip characters (incl. newline) until int available.
while (! inputScanner.hasNextInt()) {
String junk = inputScanner.findInLine(".");
if (junk == null) {
junk = inputScanner.nextLine();
}
System.out.println("Ignoring '" + junk + "'");
}
// Get integer and print both.
int num = inputScanner.nextInt();
System.out.println("Got '" + str + "' and " + num);
}
}
And the following transcript shows it in action:
Enter letter, number: Abcde42
Ignoring 'b'
Ignoring 'c'
Ignoring 'd'
Ignoring 'e'
Got 'A' and 42
I realized that my program ignores the Scanner object tastatura in try block whenever i insert wrong value and do while loop starts again so i created new object of Scanner class and called it tastatura2 and my program works fine.
Scanner tastatura = new Scanner(System.in);
boolean b = true;
int a = 0;
String r = "";
System.out.println("Please enter a letter");
r = tastatura.next();
do {
try {
Scanner tastatura2 = new Scanner(System.in);
System.out.println("Please enter numerical value");
a = tastatura2.nextInt();
b = true;
} catch (Exception e) {
System.out.println("An error occured you must enter number");
b = false;
}
} while (!b);
Just add tastatura.nextLine() in the catch block to discard the last input.
You can get out of the loop by break; when the Exception is caught ... So just add :
break;
on your catch Block :)
The catch clause would look like this :
catch (Exception e) {
System.out.println("An error occured you must enter number");
b = false;
break;
}

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;
....

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.

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
}

Categories

Resources