I'm making a small word game which requires the user to choose from options 1 to 3, 1 and 2 being a game and 3 being exit. I have the error handling set for the correct integer but not sure why the program crashes when the user inputs something thats not an integer.
import java.util.Scanner;
public class Small_Programming_Assignment {
public static void main(String[] args) {
getSelection();
substringProblem();
pointsProblem();
}
public static void getSelection() {
Scanner sc = new Scanner(System.in);
System.out.println("");
System.out.println("Welcome to the Word Games program menu.");
System.out.println("Select from one of the following options.");
System.out.println("1. Substring problem.");
System.out.println("2. Points problem.");
System.out.println("3. Exit.");
System.out.println("Enter your selection: ");
int choice = sc.nextInt();
if (choice == 1) {
substringProblem();
}
else if (choice == 2) {
pointsProblem();
}
else if (choice == 3) {
System.out.println("Goodbye!");
System.exit(0);
}
else if (!sc.hasNextInt() ) {
System.out.println("Invalid option. Try again.");
getSelection();
} else {
System.out.println("Invalid option. Try again.");
getSelection();
}
}
public static void substringProblem() {
System.out.println("Substring Problem");
getSelection();
}
public static void pointsProblem() {
System.out.println("Points Problem");
getSelection();
}
}
I'm trying to uses (!sc.hasNextInt() ) but it seems the program crashes before reaching this.
As far as I see, whenever I type in a value that's not an Integer, the program throws a Runtime Exception called InputMismatchException.
According to Oracle's Java documentation:
Thrown by a Scanner to indicate that the token retrieved does not match the pattern for the expected type, or that the token is out of range for the expected type.
The program doesn't reach your "Invalid option. Try again." statement, because the exception is thrown directly after the user input, which means, you can't provide anything other than an integer through Scanner's nextInt() method.
What you could do, if you still want to use this method, would be placing it in a try/catch statement, something like below:
int choice = 0;
try {
choice = sc.nextInt();
}
catch(InputMismatchException e) {
System.out.println("Invalid option. Try again.");
getSelection();
}
if (choice == 1) {
substringProblem();
}
else if (choice == 2) {
pointsProblem();
}
else if (choice == 3) {
System.out.println("Goodbye!");
System.exit(0);
}
else {
System.out.println("Invalid option. Try again.");
getSelection();
}
This should do the job. Now, whenever a user is typing something that cannot be parsed as an Integer, the runtime exception is thrown, is caught, so the program enters the catch block, outputs "Invalid option. Try again." and "re"-calls getSelection().
Related
So I have a while-loop where you have 3 options to choose from and you choose them by inserting a number on standard input using a scanner, my code is like this:
int option;
String request;
Scanner input2 = new Scanner(System.in);
System.out.println("Choose an option:\n" + "1-Get camera information\n" + "2-Submit Data\n"
+ "3-Exit");
while(true){
try {
option = input2.nextInt();
if (option == 1) {
System.out.println("Camera name:");
request = input2.nextLine();
while (request.length() < 3 || request.length() > 15) {
System.out.println("Name has to be between 3 and 15 characters, insert a new one:");
request = input2.nextLine();
}
CamInfoRequest info_request = CamInfoRequest.newBuilder().setName(request).build();
if (stub.camInfo(info_request).getReturn() != 0) {
System.out.println("Camera does not exist");
} else {
System.out.println(stub.camInfo(info_request).getLatitude() + " " + stub.camInfo(info_request).getLongitude());
}
} else if (option == 2) {
System.out.println("submit");
} else if(option ==3){
break;
} else{
System.out.println("Invalid option.");
}
}catch(InputMismatchException e){
System.out.println("Invalid input");
}
}
So the way this is the code enters in an infinite loop when it catches the exception where it keeps printing "Invalid input", I tried using input2.next() at the catch but then he waits for another input I don't want, I can't use input2.close() either. What can I do?
I can't use input2.close() either.
You should never close the Scanner instance for System.in as it also closes the System.in.
I tried using input2.next() at the catch but then he waits for another
input I don't want
Use Scanner::nextLine instead of Scanner::next, Scanner::nextInt etc. Check Scanner is skipping nextLine() after using next() or nextFoo()? to learn why.
Also, try to use do...while wherever you need to ask the user to enter the data again in case of an invalid entry.
Given below is a sample code incorporating these points:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int option;
boolean valid;
Scanner input2 = new Scanner(System.in);
do {
valid = true;
System.out.println("Choose an option:\n" + "1-Get camera information\n" + "2-Submit Data\n" + "3-Exit");
try {
option = Integer.parseInt(input2.nextLine());
if (option < 1 || option > 3) {
throw new IllegalArgumentException();
}
// ...Place here the rest of code (which is based on the value of option)
} catch (IllegalArgumentException e) {
System.out.println("This is an invalid entry. Please try again.");
valid = false;
}
} while (!valid);
}
}
A sample run:
Choose an option:
1-Get camera information
2-Submit Data
3-Exit
abc
This is an invalid entry. Please try again.
Choose an option:
1-Get camera information
2-Submit Data
3-Exit
6
This is an invalid entry. Please try again.
Choose an option:
1-Get camera information
2-Submit Data
3-Exit
2
Feel free to comment in case of any further doubt/issue.
Just Put the Scanner statement inside your try block
while (true) {
try {
Scanner input2 = new Scanner(System.in);
option = input2.nextInt();
if (option == 1) {
I am trying to learn try-catch uses and have to validate input so that the user must enter 1 or 2 for the program to continue. I believe I am close, but cannot seem to get the program to continue if the user enters something wrong such as '3' or '2.12'.
Here's what I have:
String input = " ";
try {
Scanner scan = new Scanner(System.in);
input = scan.next();
Integer.parseInt(input);
if (!input.equals("1") && !input.equals("2")) {
System.out.println();
System.out.println("Invalid imput! Please select '1' or '2':");
}
} catch (InputMismatchException a) {
System.out.println();
System.out.println("Invalid imput! Please select '1' or '2':");
}
I don't necessarily see the point of using InputMismatchException for your use case. Instead, if the input doesn't match what you expect, you can log an error and just prompt the user to input again.
But [Integer#parseInt()][1] can throw an exception if the input isn't an actual integer. In your original code you never actually use the result of this call, but I have done so in my answer. In this case, it does potentially make sense to use a try-catch block.
int result;
while (true) {
try {
Scanner scan = new Scanner(System.in);
input = scan.next();
result = Integer.parseInt(input);
} catch(Exception e) {
System.out.println("Could not parse input, please try again.");
continue;
}
if (result != 1 && result != 2) {
System.out.println("Invalid input! Please select '1' or '2':");
}
else {
break;
}
}
You should put in your condition the throw statement in able to your catch statement fetch the error, the code should be like this:
String input = " ";
try {
Scanner scan = new Scanner(System.in);
input = scan.next();
Integer.parseInt(input);
if (!input.equals("1") && !input.equals("2")) {
System.out.println();
System.out.println("Invalid imput! Please select '1' or '2':");
throw new InputMismatchException ();
}
} catch (InputMismatchException a) {
System.out.println();
System.out.println("Invalid imput! Please select '1' or '2':");
}
The code is expecting for positive integers but can input string and loop again until got a positive integer input value.
Scanner scanner = new Scanner(System.in);
Integer expectedOutput = -1;
public Integer getInputNumber(){
boolean valid;
String inputData;
do {
System.out.print("Enter Input Number: \t");
try {
inputData = scanner.nextLine();
// expecting positive integers
if (Integer.parseInt(inputData) > 0) {
expectedOutput = Integer.parseInt(inputData);
valid = true;
} else {
System.out.println("Invalid Input!");
valid = false;
}
} catch (Exception ex){
valid = false;
}
} while(!valid);
return expectedOutput;}
package javaapplication1;
import java.util.Scanner;
public class JavaApplication1 {
public static void main(String[] args) {
System.out.println("What is the password?");
Scanner new2 = new Scanner(System.in);
int input = 0;
while(input <= 5 )
{
String password = new2.nextLine();
if(!password.equals("bluesky123")){
System.out.println("Incorrect password");
input++;
}
else if("bluesky123".equals(password)) {
System.out.println("You got it right!");
break;
}
else if(input == 5) {
System.out.println("maximum number of attempts reached");
break;
}
}
}
}
basically, once I hit the 5 loops, it just says "incorrect password" and breaks. not the "maximum attempts" message.
Allow me to annotate:
This if statement will always be evaluated:
if(!password.equals("bluesky123")){
System.out.println("Incorrect password");
input++;
}
This if statement will only be evaluated if the password is "bluesky123". In this case, it will always evaluate to true.
else if("bluesky123".equals(password)) {
System.out.println("You got it right!");
break;
}
There is no case when this if statement will ever be evaluated. Once if-else finds a statement that is true, it will skip all others in that section.
else if(input == 5) {
System.out.println("maximum number of attempts reached");
break;
}
In your case, you should consider a nested if (i.e. an if inside another if).
while(input <= 5 )
{
String password = new2.nextLine();
if(!password.equals("bluesky123")){
System.out.println("Incorrect password");
input++;
}
else {
System.out.println("You got it right!");
break;
}
if((input == 5) && (!password.equals("bluesky123"))) {
System.out.println("maximum number of attempts reached");
break;
}
}
Your logic has some flaws. You have to pay attention to how JAVA processes if / else if
https://www.tutorialspoint.com/java/if_else_statement_in_java.htm
I tested your code it is working! The only thing that you need to do is to move the follow line to inside the while loop
System.out.println("What is the password?");
Doing this it will print "Incorrect password" and then it will print again
"What is the password?"
Because in the way that it is working now seems that the software is not waiting the password to be retyped when in fact it is.
I'm doing a java program for an assignment, and one of the exceptions are that the user cannot input a value for a row or column that does not exist. i.e If the board was 5x7 and the user entered a column of value 10 the screen would print "Error: Invalid column" . However i'm unsure how to do this final exception and i need to submit it today. If anyone could help i'd really appreciate it! Here is my code for the makeGuess() function:
public void makeGuess(){
//guesses is for keeping track of your guesses
boolean cont=true;
int rowGuess;
int columnGuess;
do{
System.out.println("Enter a row to guess >");
rowGuess = (input.nextInt()-1);
if(rowGuess<=0){
System.out.println("You did not enter a positive Integer.Please try again");
cont=false;}
else{
cont=true;}
}
while (cont==false);
do{
System.out.println("Enter a column to guess >");
columnGuess = (input.nextInt()-1);
if(columnGuess <=0){
System.out.println("You did not enter a positive integer.Please try again");
cont=false;
} else{
cont=true;
}
}while(cont==false);
Assuming that the rest of your code works, you could simply alter your if statements to ensure the entry is valid.
Using the OR operator ||:
if (columnGuess <= 0 || columnGuess >= 10){
System.out.println("Error: invalid Column");
}
just as you have an if statement to test if the number is too small you also need to test if it is too big
public void makeGuess(){
//guesses is for keeping track of your guesses
boolean cont=true;
int rowGuess;
int columnGuess;
do{
System.out.println("Enter a row to guess >");
rowGuess = (input.nextInt()-1);
if(rowGuess<=0){
System.out.println("You did not enter a positive Integer.Please try again");
cont=false;
}else if(rowGuess>7){
System.out.println("You did not enter a small enough Integer.Please try again");
cont=false;
}else{
cont=true;
}
}while (cont==false);
do{
System.out.println("Enter a column to guess >");
columnGuess = (input.nextInt()-1);
if(columnGuess <=0){
System.out.println("You did not enter a positive integer.Pleasetry again");
cont=false;
}else if(columnGuess>5){
System.out.println("You did not enter a small enough Integer.Please try again");
cont=false;
} else{
cont=true;
}
}while(cont==false);
A better way to do this in my experience is to create your own exception
public class BadMoveException extends Exception {
BadMoveException(Exception ex) {
super(ex);
}
BadMoveException(String ex) {
super(ex);
}
}
Make makeGuess throw BadMoveException, and then for any of the invalid moves the user can make, you can create a BadMoveException with that, and print it in the catch { } block outside of makeGuess
while (!gameOver) {
try {
makeGuess();
}
catch (BadMoveException ex) {
System.out.println("You tried to make an invalid move:" + ex.getMessage());
}
}
Ive no idea if my title made sense but here is the code ©
import java.util.InputMismatchException;
import java.util.Scanner;
public class Gussing {
public static void theGame(Scanner input){
int randomNum= (int)(Math.random()*101);//randomizes a number between 0-100 inclusive of both
System.out.println(randomNum); //for debugging purposes
int attemptCounter = 0; //counts how many attempts the user make
System.out.print("Welcome to the guess-the number game! Enter your guess: ");
while(true){
System.out.println("here is bad input");
try{
System.out.println("here is after the bad input");
int userInput= input.nextInt();
if (userInput==randomNum) //when usr input and generated random number are equal we print how many attempts
{
attemptCounter++;
System.out.println("Congrats you made the right guess after "+ attemptCounter + " attempts!");
break;
}
if(userInput<randomNum){
attemptCounter++;
System.out.print("Too low! Try again: ");
}
else {
attemptCounter++; //else clause does the opposite of if clause
System.out.print("Too high! Try again: ");
}
}
catch( Exception e){
System.out.println("Invalid input");
}
}
}
public static void main(String[] args){
Scanner input = new Scanner (System.in);
theGame (input);
System.out.println("Play again? (Y/N)");
try{
char answer=input.next().toLowerCase().charAt(0);
//toLowerCase method so that N =n = no !
if (answer =='y') theGame (input);
else if (answer =='n') System.out.println("Good bye");
input.close(); //no more input data
}
catch(Exception e){
System.out.println("invalid input");
}
}
}
so when the user types in the wrong type i.e not int it prints out invalid input. This is however not the problem the problem is that it prints that out infinitely. I tried adjusting the try catchblocks but it didnt help at all
nextInt doesnt remove non-integer data from the input buffer so it gets recycled indefinitely unless the data is consumed. In this case an InputMismatchException is thrown by the method so you could write your exception block as
} catch (InputMismatchException e) {
System.out.println("Invalid input " + input.nextLine());
}