Taking keyboard input and running checks on it - java

I have the following method
public static int modeChooser(){
int choice = 0;
Scanner kb = new Scanner(System.in);
while(choice == 0){
try {
choice = kb.nextInt();
} catch (Exception e) {
continue;
}
if(choice < 1 || choice > 5){
continue;
}
}
return choice;
}
The goal is to only allow the user to put in 1,2,3,4, or 5;
If the user types a string or a too high/low number, the method should just restart until i have the proper int.
Here is an example for the flow:
User types: 1 -> all ok
User types: saddj -> method restarts -> user types 3 --> all ok
Any ideas?

Change to:
do {
// read choice value
if (choice < 1 || choice > 5) {
// hint to user
}
} while(choice < 1 || choice > 5);

I think you can simply put your check in the while condition itself as below:
while(choice < 1 || choice > 5){
try {
choice = kb.nextInt();
} catch (Exception e) {
//ignore the exception and continue
}
}

This way actually works fine:
public static int modeChooser(){
int choice = 0;
Scanner kb = new Scanner(System.in);
while(choice == 0){
try {
choice = kb.nextInt();
} catch (Exception e) {
System.out.println("Sorry but you have to enter 1,2,3,4, or 5! Please try again.");
choice = modeChooser();
}
}
if(choice < 1 || choice > 5){
System.out.println("Sorry but you have to enter 1,2,3,4, or 5! Please try again.");
choice = modeChooser();
}
return choice;
}

if(choice >= 1 && choice <= 5)
break;
else
choice = 0;

If kb.NextInt() fails the data in the input stream remains, you need to skip past it. If you don't skip the invalid data the loop will continuously try, and fail, to read the invalid input resulting in an infinite loop.
You can use kb.next() to skip over the invalid input:
while (true)
{
try
{
choice = kb.nextInt();
if(choice >= 1 && choice <= 5) break;
}
catch (InputMismatchException e)
{
e.printStackTrace();
kb.next();
}
}

I think it's better to use the Scanner.nextLine() and Integer.parseInt() methods:
while(choice < 1 || choice > 5){
try {
choice = Integer.parseInt(kb.nextLine());
} catch (Exception e) {
//...print error msg
}
}

You could include your condition on choice directly in the while condition:
while(choice < 1 || choice > 5){
try {
choice = kb.nextInt();
} catch (Exception e) {
continue;
}
}
(In your current code, is the user enters 7, choice takes that value, the while condition becomes false and your method returns 7, which it should not).
And instead of catching an exception, you could use the hasNextInt() method to make the code cleaner:
public static int modeChooser() {
int choice = 0;
Scanner kb = new Scanner(System.in);
while (choice < 1 || choice > 5) {
if (!kb.hasNextInt()) {
kb.next();
} else {
choice = kb.nextInt();
}
}
return choice;
}
If you do want to use a recursive method, it could look like:
public static int modeChooser() {
Scanner kb = new Scanner(System.in);
while (!kb.hasNextInt()) {
kb.next();
}
int choice = kb.nextInt();
return (choice >= 1 && choice <= 5) ? choice : modeChooser();
}

Related

I can't use NumberFormatExeption. The program should continue even if the user input a string or non-number

Guessing the number
import java.util.*;
public class LabExer5A
{
public static void main(String args[])
{
Scanner Input = new Scanner (System.in);
System.out.println("Guess a number between 1 and 50");
int JPS_Guess = Input.nextInt();
int JPS_CorrectNum = 25;
int JPS_NextGuess;
do
{
try
{
if (JPS_Guess == JPS_CorrectNum)
{
System.out.println("You got it in ");
}
else if (JPS_Guess < JPS_CorrectNum && JPS_Guess >= 1)
{
System.out.println("Too low. Try again.");
JPS_NextGuess = Input.nextInt();
JPS_Guess = JPS_NextGuess;
}
else if (JPS_Guess > JPS_CorrectNum && JPS_Guess <= 50)
{
System.out.println("Too High. Try again.");
JPS_NextGuess = Input.nextInt();
JPS_Guess = JPS_NextGuess;
}
else if(JPS_Guess < 1 || JPS_Guess > 50)
{
throw new InputMismatchException();
}
}
catch(InputMismatchException e)
{
System.out.println("Invalid value. Please enter a number between 1 and 50: ");
JPS_NextGuess = Input.nextInt();
JPS_Guess = JPS_NextGuess;
}
catch (NumberFormatException ex)
{
System.out.println("Error - Enter Numerical Values Only");
JPS_NextGuess = Input.nextInt();
JPS_Guess = JPS_NextGuess;
}
}
while (JPS_Guess != JPS_CorrectNum);//will rerun the program until the user guess the correct number
}
}
}
}
I'm not sure where I made the mistake. Either the use of the throw catch or maybe because of the way I rerun the program. I'm pretty new to using exception and try-catch Please help and be kind. Thank you.
nextInt() actually throws InputMismatchException when you input other data type so you can directly use the catch for InputMismatchException and you should add Input.next() so that the scanner will take in the non integer input
Another thing is that Input.nextInt() should always be inside the try/catch. In your code, the exception will not be catched for the first input and after you input any wrong value.
catch(InputMismatchException e)
{
System.out.println("Invalid value. Please enter a number between 1 and 50: ");
JPS_NextGuess = Input.nextInt();
JPS_Guess = JPS_NextGuess;
}
I have modified your code to be simpler. I suggest you use boolean to keep track of whether the number is guessed so you don't have to interchange the guess. Also, good indentation formatting helps reading.
import java.util.*;
public class LabExer5A
{
public static void main(String args[])
{
Scanner Input = new Scanner (System.in);
System.out.println("Guess a number between 1 and 50");
int JPS_CorrectNum=25;
boolean isGuessed=false;
do
{
try
{
int JPS_Guess = Input.nextInt();
if (JPS_Guess == JPS_CorrectNum)
{
System.out.println("You got it in ");
isGuessed=true;
}
else if (JPS_Guess < JPS_CorrectNum && JPS_Guess >= 1)
{
System.out.println("Too low. Try again.");
}
else if (JPS_Guess > JPS_CorrectNum && JPS_Guess <= 50)
{
System.out.println("Too High. Try again.");
}
else if(JPS_Guess < 1 || JPS_Guess > 50)
{
throw new InputMismatchException();
}
}
catch(InputMismatchException e)
{
System.out.println("Invalid value. Please enter a number between 1 and 50: ");
Input.next();
}
}
while (!isGuessed);//will rerun the program until the user guess the correct number
}
}

Java- Using if statement inside a loop

I wrote a small code :
System.out.println("Please enter a number");
int number = scan.nextInt();
if(number == 1) {
System.out.println("Number is 1");
} else if(number == 2) {
System.out.println("Number is 2");
} else {
System.out.println("Invalid selection");
}
When the user enters a number different than 1 and 2, user gets "Invalid selection" message and then code terminates. I don't want it to terminate, I want it to run again until user writes 1 or 2. I tried do-while loop but it become an infinite loop. What are your suggestions?
You can use while loop here
Scanner scanner = new Scanner(System.in);
boolean status = true;
while (status) { // this runs if status is true
System.out.println("Please enter a number");
int number = scanner.nextInt();
if (number == 1) {
System.out.println("Number is 1");
status=false; // when your condition match stop the loop
} else if (number == 2) {
System.out.println("Number is 2");
status=false;// when your condition match stop the loop
} else{
System.out.println("Invalid selection");
}
}
Try this...
int number;
do{
System.out.println("Please enter a number");
number = scan.nextInt();
if(number == 1)
{
System.out.println("Number is 1") ;
}
else if(number == 2)
{
System.out.println("Number is 2") ;
}
else
{
System.out.println("Invalid selection") ;
}
}while(number!=1 && number!=2);
I recommend you check if there is an int with Scanner.hasNextInt() before you call Scanner.nextInt(). And, that makes a nice loop test condition if you use it in a while loop.
Scanner scan = new Scanner(System.in);
System.out.println("Please enter a number");
while (scan.hasNextInt()) {
int number = scan.nextInt();
if (number == 1) {
System.out.println("Number is 1");
break;
} else if (number == 2) {
System.out.println("Number is 2");
break;
} else {
System.out.println("Invalid selection");
}
}
// ...
#Dosher, reposting #Raj_89's answer with correction in while loop condition. Please notice While loop condition
int number = 0;
do{
System.out.println("Please enter a number");
Scanner scan = new Scanner(System.in);
number = scan.nextInt();
if(number == 1)
{
System.out.println("Number is 1") ;
}
else if(number == 2)
{
System.out.println("Number is 2") ;
}
else
{
System.out.println("Invalid selection") ;
}
}while(number==1 || number==2);

Exception in do while loop

I have this piece of code:
do {
try {
input = sc.nextInt();
}
catch(Exception e) {
System.out.println("Wrong input");
sc.nextLine();
}
}
while (input < 1 || input > 4);
Right now, if I input 'abcd' instead of integer 1-4, it gives message "Wrong Input" and the program loops, how can I make it so that it also gives "Wrong Input" when I entered integer that doesn't fulfill the boolean (input < 1 || input >4)?
So that if I entered 5, it will also give me "Wrong Input".
Add this:
if(input < 1 || input > 4) {
System.out.println("Wrong input");
}
after input = sc.nextInt();
As of now, your try-catch block is checking if input is an int type. The do-while loop is checking input after it has been entered, so it is useless. The condition must be checked after the user enters what he/she wants. This should fix it:
do
{
try
{
input = sc.nextInt();
if(input < 1 || input > 4) // check condition here.
{
System.out.println("Wrong input");
}
}
catch(Exception e)
{
System.out.println("Expected input to be an int. Try again."); // tell user that input must be an integer.
sc.nextLine();
}
} while (input < 1 || input > 4);
You can also do this:
while (true) {
try {
input = sc.nextInt();
if (input >= 1 && input <= 4) {
break;
}
} catch (Exception e) {
System.out.println("Wrong input");
}
sc.nextLine();
}

Infinite looping; do not understand how

In the code below, when I input anything other than an integer value the code does not ask for my input again and just loops the string outputs infinitely. A little help...
int choice = 0;
while(choice == 0)
{
try
{
System.out.println("Start by typing the choice number from above and hitting enter: ");
choice = input.nextInt();
}
catch(Exception e)
{
}
if ((choice == 1) || (choice == 2) || (choice == 3))
{
break;
}
else
{
System.out.println("Invalid choice number. Please carefully type correct option.");
choice = 0;
}
}
When you input a non-integer it will not be consumed. You need to scan past it. This can be done by, for example, adding a input.nextLine() statement to your catch block. This will consume the invalid input and allow your program to read new data.
This will solve your problem:
catch(Exception e)
{
input.nextLine(); // Consume the invalid line
System.out.println("Invalid choice number. Please carefully type correct option.");
}
You could also read the line as a string and try to parse it as a number using Scanner.nextLine and Integer.parseInt, but I prefer using nextInt for integers. It makes the purpose of the code more clear (in my opinion).
When nextInt is used and the next input is not an int, it will throw an exception but not consume the data, i.e. the next call will return immediately because the data is still present.
You can fix this by calling the skip method with a pattern like [^0-9]* to skip all invalid input. Then an input like "aaa3" would work. If you want to ignore everything, use .* as pattern.
The trouble is that you are not consuming the remaining data in the stream. I solved it with the following code, although you will want to document you code better before you use it in a program:
int choice = 0;
while(choice == 0)
{
try
{
System.out.print("Start by typing the choice number from above and hitting enter: ");
choice = input.nextInt();
}
catch(Exception e)
{
input.next();
System.out.println("Invalid choice number. Please carefully type correct option.");
}
if ((choice == 1) || (choice == 2) || (choice == 3))
{
break;
}
choice = 0;
}
You can simplify and reduce your code as follows:
int choice;
System.out.println("Start by typing the choice number from above and hitting enter: ");
while(true)
{
try {
choice = input.nextInt();
if ((choice == 1) || (choice == 2) || (choice == 3))
break;
} catch(InputMismatchException e) { // handle only the specific exception
input.nextLine(); // clear the input
}
System.out.println("Invalid choice number. Please carefully type correct option.");
}
Are you using Scanner(system.in); from the import java.util.Scanner; package?
Try adding input.nextLine(); in the catch to clear the value to stop the infinite loop.
public static void main(String[] args) {
int choice = 0;
Scanner input = new Scanner(System.in);
while(choice == 0)
{
try
{
System.out.println("Start by typing the choice number from above and hitting enter: ");
choice = input.nextInt();
}
catch(Exception e)
{
input.nextLine();
System.out.println("Invalid choice number. Please carefully type correct option.");
}
if ((choice == 1) || (choice == 2) || (choice == 3))
{
break;
}
else
{
System.out.println("Invalid choice number. Please carefully type correct option.");
choice = 0;
}
}
}
Looks like in the line choice = input.nextInt();
choice value is always 0. Print choice soon after that.
Also for non integer value add a condition to break from the loop.

Resume loop after caught exception

I am catching an inputMismatchException in my main method and want my do-while loop to iterate again after the exception is caught. I even coded an explicit continue statement but that didn't work. How can I do so?
public class AddressBookApp {
public static void main(String[] args) {
AddressBook abook = new AddressBook();
System.out.println("Welcome to the Address Book Application\n");
Scanner sc = new Scanner(System.in);
int menuNumber = 4;
loop:
do {
abook.menu();
try{
menuNumber = sc.nextInt();
System.out.println();
if (menuNumber < 1 || menuNumber > 4){
System.out.println("Please enter a valid menu number\n");
} else if (menuNumber == 1) {
abook.printEntries();
} else if (menuNumber == 2) {
abook.addEntry();
} else if (menuNumber == 3) {
abook.removeEntry();
} else {
System.out.println("Thanks! Goodbye.");
sc.close();
return;
}
} catch (InputMismatchException ime) {
System.out.println("Please enter an integer");
sc.next();
continue loop;
}
} while (menuNumber != 4);
sc.close();
}
}
You left menuNumber equal to 4, which is the termination condition of your loop. Of course your loop will end.
You initialized menuNumber to 4, but do not change it in case of an exception. The loop does attempt to continue, but exits because the statement menuNumber != 4 is false.
int menuNumber = 4;
loop:
do {
abook.menu();
try{
menuNumber = sc.nextInt();
System.out.println();
if (menuNumber < 1 || menuNumber > 4){
System.out.println("Please enter a valid menu number\n");
} else if (menuNumber == 1) {
abook.printEntries();
} else if (menuNumber == 2) {
abook.addEntry();
} else if (menuNumber == 3) {
abook.removeEntry();
} else {
System.out.println("Thanks! Goodbye.");
sc.close();
return;
}
} catch (InputMismatchException ime) {
System.out.println("Please enter an integer");
sc.next();
continue loop;
}
} while (menuNumber != 4);
Try this
} catch (InputMismatchException ime) {
if (fatal(ime)) {
throw ime;
} else {
// try again
continue;
}
The loop doesn't continue because an exception of a type OTHER than InputMistmatchException is being thrown. Change the catch to:
catch (Exception e)
or at least add that all encompassing catch condition.
A better solution is to inspect exactly what exception is being thrown and why, and then fix the problem leading to the exception. Having an all encompassing catch with a continue statement could, in theory, lead to an infinite loop because menuNumber is not incremented.

Categories

Resources