I have written some code to check if the user has entered a number between 1 and 5, and now I would also like my code to allow the user to enter the letters A, S, D or M.
Is there a way to combine the code where I can have it identify whether the user has entered 1-5 or A, S, D, M?
How do I edit the code below so the user can enter either an Integer or a character? Do I have to write a snippet of code underneath the loop for it to identify that a user did not enter 1-5 but did enter A, S, D, or M, as in break out of the loop? Or is it a separate loop all together. I am so confused!
import java.util.InputMismatchException;
import java.util.Scanner;
public class Selection {
Scanner readInput = new Scanner(System.in);
int selectionOne() {
int inputInt;
do { //do loop will continue to run until user enters correct response
System.out.print("Please enter a number between 1 and 5, A for Addition, S for subtraction, M for multiplication, or D for division: ");
try {
inputInt = readInput.nextInt(); //user will enter a response
if (inputInt >= 1 && inputInt <=5) {
System.out.print("Thank you");
break; //user entered a number between 1 and 5
} else {
System.out.println("Sorry, you have not entered the correct number, please try again.");
}
continue;
}
catch (final InputMismatchException e) {
System.out.println("You have entered an invalid choice. Try again.");
readInput.nextLine(); // discard non-int input
continue; // loop will continue until correct answer is found
}
} while (true);
return inputInt;
}
}
I suggest instead of using an int input, just use a String input and convert it to an integer when you need to. You can use Integer.parseInt(String) to convert a String to an int.
So when you check if the input is valid, you need to check if the input is equal to "A", "S", "M" or "D", or any values from 1-5 when it is converted to an int.
So to check if it's one of the characters, you could do this:
if (input.equals("A") || input.equals("S") || input.equals("M") || input.equals("D"))
And then to test if it's an int of value 1 through 5, you could do this:
if (Integer.parseInt(input) >= 1 && Integer.parseInt(input) <= 5)
Just parse the input to an int and then check the range as you already have done.
The return type of this method will be String now, instead of int. If you need it to be an int for whatever reason, you can just parse the value to an int and then return that instead. But I just returned it as a String.
The last thing I changed was the catch block. Now, instead of an InputMismatchException (because they can enter Strings now, I changed it to NumberFormatException, which would happen if a String that could not be converted to an int was attempted to be. For example, Integer.parseInt("hello") will throw a NumberFomatException because "hello" can not be represented as an integer. But, Integer.parseInt("1") would be fine and would return 1.
Note that you should test the String equivalence first so that you don't go into your block before you have a chance to test all conditions you need to.
The method would look like this:
String selectionOne() {
String input;
do { //do loop will continue to run until user enters correct response
System.out.print("Please enter a number between 1 and 5, A for Addition, S for subtraction, M for multiplication, or D for division: ");
try {
input = readInput.nextLine(); //user will enter a response
if (input.equals("A") || input.equals("S") || input.equals("M") || input.equals("D")) {
System.out.println("Thank you");
break; //user entered a character of A, S, M, or D
} else if (Integer.parseInt(input) >= 1 && Integer.parseInt(input) <= 5) {
System.out.println("Thank you");
break; //user entered a number between 1 and 5
} else {
System.out.println("Sorry, you have not entered the correct number, please try again.");
}
continue;
}
catch (final NumberFormatException e) {
System.out.println("You have entered an invalid choice. Try again.");
continue; // loop will continue until correct answer is found
}
} while (true);
return input;
}
As #MarsAtomic mentioned, first thing you should change your input to String instead of an int so you can easily handle both characters and digits.
Change:
int inputInt;
To:
String input;
Then change:
inputInt = readInput.nextInt();
To:
input = readInput.next();
To accommodate reading String instead of int.
Now you reach at 2 main cases (and 2 subcases):
1) input is a single character
a) input is a single digit from 1-5
b) input is a single character from the set ('A', 'S', 'D', 'M')
2) input is an error value
Also, since you are not calling Scanner.nextInt, you don't need to use the try/catch statement and can print your errors in else blocks.
Furthermore, you should have your method return a char or a String instead of an int so you can return both 1-5 or A,S,D,M. I will assume you want to return a char. If you want to return a String instead, you can return input instead of return val in the code bellow.
NOTE: The code bellow can be simplified and shortened, I just added variables and comments in an attempt to make each step clear to what is being read or converted. You can look at #mikeyaworski's answer for a more concise way of doing this.
Here is how your code could look like:
char selectionOne() {
String input;
do {
input = readInput.next();
// check if input is a single character
if(input.length() == 1) {
char val = input.charAt(0);
// check if input is a single digit from 1-5
if(Character.isDigit(val)) {
int digit = Integer.parseInt(input);
if (digit >= 1 && digit <=5) {
System.out.print("Thank you");
return val; // no need to break, can return the correct digit right here
} else {
System.out.println("Sorry, you have not entered the correct number, please try again.");
}
} else {
// check if input is in our valid set of characters
if(val == 'A' || val == 'S' || val == 'M' || val == 'D') {
System.out.print("Thank you");
return val; // return the correct character
} else {
System.out.println("Sorry, you have not entered the correct character, please try again.");
}
}
} else {
System.out.println("Sorry, you have not entered the correct input format, please try again.");
}
} while(true);
}
If your input can be both characters and letters, why not change to looking for a char or String? Then, you can look for "1" or "A" without any trouble.
Related
After a switch statement I would like to request a 'Y' or 'N' statement and print out a statement for the respective response. How can I declare the input char, then provide a scanner input for that value?
I've tried using input as a char and an integer. I've also tried using the boolean method as well.
import java.util.*;
public class Dowhile {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int x;
System.out.println("0,1,-1: ");
x = in.nextInt();
switch(x)
{
case 1:
System.out.println("Positive");
break;
case -1:
System.out.println("Negative");
break;
case 0:
System.out.println("Zero");
break;
default:
System.out.println("You're a bad person!");
break;
}
char input = (('Y'||'N'));
System.out.println("Enter 'Y' or 'N'");
in.nextInt();
if(input = 'Y')
System.out.println("OK");
else
System.out.println("wow");
}}
I expect the output to be the println response for the respective input.
I would try something like this:
System.out.println("Enter 'Y' or 'N'");
char input = in.next("Y|N").charAt(0);
if('Y' == input)
System.out.println("OK");
else
System.out.println("wow");
The in.next("Y|N") part requests either a 'Y' or a 'N' (the String "Y|N" is interpreted as a regular expression) and returns the result as a String. The charAt(0) function returns the first (and only) character from this String.
Note that this approach throws an exception if you enter neither 'Y' nor 'N'.
If you want to avoid the exception you can use the following code snippet:
System.out.println("Enter 'Y' or 'N'");
char input = in.next(".").charAt(0);
if('Y' == input)
System.out.println("OK");
else if ('N' == input)
System.out.println("wow");
else
System.out.println("You haven't entered a valid character");
But beware, because your first call to in.nextInt() will still fail if someone enters something that isn't an integer.
Assuming you don't need to expand your program to do anything other than print to the console, the following would be the approach I'd take:
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("0,1,-1: ");
int x = in.nextInt();
System.out.println(
x == 1 ? "Positive" :
x == -1 ? "Negative" :
x == 0 ? "Zero" :
"You're a bad person!"
);
System.out.println("Enter 'Y' or 'N'");
System.out.println(in.next().equalsIgnoreCase("Y") ? "OK" : "wow");
in.close();
}
Ternary operators are used for checking the conditions and printing to the console without switch or if statements.
I'm trying to make this Sentinel program more robust by continuing it even when incorrect user inputs are received. I've gotten it to work if the user input is a different int, but if it is a string, or anything else really, the program crashes.
My current code attempt is this:
} else if (userInt != 1 && userInt != 2 && userInt != 3 && userInt != 4 && userInt != 5 && userInt !=6
|| userInt instanceof String) {
The first part of this code works fine at checking if the user input is a different in. The instanceof statement gives the error of "incompatible operand types int and String"
Should I even be using an instanceof statement? Is there a better way to check for this?
This is the whole method:
public static void printMenu() {
Scanner userInput2 = new Scanner(System.in);
String menu = new String(" Please choose from the following menu: \n 1. Rock paper Scissors\n 2. "
+ "Tip Calculator\n 3. "
+ "Number Adding\n 4. Guessing Game\n 5. Random\n 6. Exit");
System.out.println(menu);
int userInt = userInput2.nextInt();
if (userInt == 1) {
System.out.println(" You asked to play Rock Paper Scissors");
System.out.println(" Launching Rock Paper Scissors... \n");
RockPaperScissors gameRun1 = new RockPaperScissors();
gameRun1.main(null);
} else if (userInt == 2) {
System.out.println(" You asked to run the Tip Calculator");
System.out.println(" Launching the Tip Calculator... \n");
TipCalculator gameRun2 = new TipCalculator();
gameRun2.main(null);
} else if (userInt == 3) {
System.out.println(" You asked to run the Number Adding game");
System.out.println(" Launching the Number Adding game... \n");
NumberAddingGame gameRun3 = new NumberAddingGame();
gameRun3.main(null);
} else if (userInt == 4) {
System.out.println(" You asked to play GuessingGame");
System.out.println(" Launching GuessingGame... \n");
GuessingGame gameRun4 = new GuessingGame();
gameRun4.main(null);
} else if (userInt == 5) {
System.out.println(" You asked for a random game");
option5();
} else if (userInt == 6) {
System.out.println( "Thank you for using Conner's Sentinel");
// figure out how to terminate the program from here
} else if (userInt != 1 && userInt != 2 && userInt != 3 && userInt != 4 && userInt != 5 && userInt !=6
|| userInt instanceof String {
System.out.println("Not a valid input, type 1-6");
printMenu();
}
printMenu();
}
There is no way to check if the next input was an int like you are doing (userInput2.nextInt() can only return an int), instead you have to check before you assign the result. Something like,
if (userInput2.hasNextInt()) {
int userInt = userInput2.nextInt();
if (userInt == 1) {
System.out.println(" You asked to play Rock Paper Scissors");
System.out.println(" Launching Rock Paper Scissors... \n");
RockPaperScissors gameRun1 = new RockPaperScissors();
gameRun1.main(null);
} else if (userInt == 2) {
System.out.println(" You asked to run the Tip Calculator");
System.out.println(" Launching the Tip Calculator... \n");
TipCalculator gameRun2 = new TipCalculator();
gameRun2.main(null);
} else if (userInt == 3) {
System.out.println(" You asked to run the Number Adding game");
System.out.println(" Launching the Number Adding game... \n");
NumberAddingGame gameRun3 = new NumberAddingGame();
gameRun3.main(null);
} else if (userInt == 4) {
System.out.println(" You asked to play GuessingGame");
System.out.println(" Launching GuessingGame... \n");
GuessingGame gameRun4 = new GuessingGame();
gameRun4.main(null);
} else if (userInt == 5) {
System.out.println(" You asked for a random game");
option5();
} else if (userInt == 6) {
System.out.println("Thank you for using Conner's Sentinel");
// figure out how to terminate the program from here
} else {
System.out.println("Not a valid input, type 1-6");
printMenu();
}
} else {
userInput2.nextLine(); // <-- consume the non-number
System.out.println("Not a valid number, type 1-6");
printMenu();
}
Instead of "expecting" an int...
int userInt = userInput2.nextInt();
You should "expect" a String...
int actualInput = userInput2.nextLine();
From this you could then use Integer.parseInt(String) in an attempt to parse the String to an int, this will give you your first chance to validate the value.
The problem with this is Integer.parseInt(String) can throw a NumberFormatException, and you really should avoid making logic decisions based on exceptions.
Another approach might be to use a regular expression instead, something like...
if (actualInput.matches("^\\d*")) {
// This is a number, safe to parse to int
} else {
// This is not a number and is not safe to be parsed
}
Once you're satisfied that the actualInput is a number, you could use another Scanner to get the next int...
Scanner safeScanner = new Scanner(actualInput);
int userInt = safeScanner.nextInt();
as an example
userInt instanceof String will always be false, since userInt is an int. If it is an int, you don't need to check for instanceof string.
What you meant is to proof check the string from user input with StringUtils.isNumeric and reduce your other expressions to:
if 1<= userInt && userInt <=6
Should I even be using an instanceof statement? Is there a better way
to check for this?
Even if some other string, non numeric, could be converted to int and result into a value between 1 and 6, this way it would be rejected. Keep the numeric check, yes, just the correct one, StringUtils.isNumeric .
If you opt to have userInt as String, instead, then turn the other expression into if 1<= Integer.parseInt(userInt) && Integer.parseInt(userInt) <=6
First of all, after you write something like this:
int userInt = userInput2.nextInt();
your userInt is declared as an int, and can be nothing but a int. So writing something like this makes no sense:
userInt instanceof String
Because here, you already know that userInt is an int, because you declared it so.
The problem (where the exception, or crash as you called it, occurred) is elsewhere. It will happen at the call to nextInt().
Read the documentation for Scanner.nextInt(), under the exceptions, it states:
Throws:
InputMismatchException - if the next token does not match the Integer regular expression, or is out of range
So that is exactly what happens.
You have several choices, two of which:
catch the exception, and handle it the way you want it to be handled
Use of Scanner.hasNextInt().
I already see a growing number of alternative approaches.
Also most people would translate that chain of if/else if statements into a switch/case/default construct.
Then an other problem in your printMenu() method, it is endlessly recursive. Even though it is just user input, and it might have a limited timespan, with limited user entries before it exits, in theory you could reach a situation where you get a StackOverflowException. This implementation begs to be converted from recursive to iterative to avoid overallocation of objects (memory leak) and having a stack that grows forever.
import java.util.Scanner;
public class main {
public static void main(String[] args) {
int number = 0;
Scanner input = new Scanner(System.in);
System.out.print("Please enter the number of sides");
number = input.nextInt();
if (number == 1) {
System.out.println("Circle");
}
if (number == 3) {
System.out.println("Triangle");
}
if (number == 4) {
System.out.println("quadrilateral");
}
else {
System.out.println("Incorrect Input");
}
}
}
Hello, I am trying to use the if statement. Can anyone advise me how to loop if statements? Because I get this as a result for example:
circle
Incorrect Input.
Also, How could I repeat the scanner so it allowed me to type another input?
Currently, the else clause is only associated to the last if block i.e. if (number == 4) {...} This means if any of the other if blocks are executed, it will still print "Incorrect Input". The solution is to use else if instead of separate if's.
if (number == 1) {
System.out.println("Circle");
}else if (number == 3) {
System.out.println("Triangle");
}else if (number == 4) {
System.out.println("quadrilateral");
}
else {
System.out.println("Incorrect Input");
}
You can use switch case (see : https://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html).
And you can check the type of number or string with instanceof.
For your second part question, I guess you're looking for something like a do....while loop, you can set up some condition like if the input result is not a number, then it will stuck in the loop until the user type in a number then only go in the the if, else-if statement
im trying to do two checks with a while loop:
1) To show "error" if the user inputs something other than an int
2) Once the user entered an int, if it is one digit, show "two digits only" and keep the loop on until a two digit int has been entered (so an IF should be used as well)
Currently I only have the first part done:
Scanner scan = new Scanner(System.in);
System.out.println("Enter a number");
while (!scan.hasNextInt()) {
System.out.println("error");
scan.next();
}
However, if possible, I would like to have both checks in one while loop.
And that's where I'm stuck...
Since you already have two answers. This seems a cleaner way to do it.
Scanner scan = new Scanner(System.in);
String number = null;
do {
//this if statement will only run after the first run.
//no real need for this if statement though.
if (number != null) {
System.out.println("Must be 2 digits");
}
System.out.print("Enter a 2 digit number: ");
number = scan.nextLine();
//to allow for "00", "01".
} while (!number.matches("[0-9]{2}"));
System.out.println("You entered " + number);
As said above you should always take the input in as string and then try
and parse it for an int
package stackManca;
import java.util.Scanner;
public class KarmaKing {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String input = null;
int inputNumber = 0;
while (scan.hasNextLine()) {
input = scan.next();
try {
inputNumber = Integer.parseInt(input);
} catch (Exception e) {
System.out.println("Please enter a number");
continue;
}
if (input.length() != 2) {
System.out.println("Please Enter a 2 digit number");
} else {
System.out.println("You entered: " + input);
}
}
}
}
First take the input as a String. If it is convertible to Int then you do your checks, else say 2 digit numbers are acceptable. If it is not convertible to a number throw an error. All this can be done in one while loop. And you would like to have a "Do you want to continue? " kind of a prompt and check if the answer is "yes" / "No." Break from the while loop accordingly.
To have it as one loop, it's a bit messier than two loops
int i = 0;
while(true)
{
if(!scan.hasNextInt())
{
System.out.println("error");
scan.next();
continue;
}
i = scan.nextInt();
if(i < 10 || >= 100)
{
System.out.println("two digits only");
continue;
}
break;
}
//do stuff with your two digit number, i
vs with two loops
int i = 0;
boolean firstRun = true;
while(i < 10 || i >= 100)
{
if(firstRun)
firstRun = false;
else
System.out.println("two digits only");
while(!scan.hasNextInt())
{
System.out.println("error");
scan.next();
}
i = scan.nextInt();
}
//do stuff with your two digit number, i
In this Java program the user is supposed to guess a number from 1 to 100, and then if you press S it shows you a summary of the tries. The problem is that I am taking the input string and converting it to a number so I can compare it to the range, but then I also need to be able to use that string as a menu input.
UPDATE How can i make the program go back to the menu option after the user guesses correctly. So after the user wins, i would like for the problem to display the summary report which can be otherwise accessed by using S
Here is my code
public class GuessingGame {
public static void main(String[] args) {
// Display list of commands
System.out.println("*************************");
System.out.println("The Guessing Game-inator");
System.out.println("*************************");
System.out.println("Your opponent has guessed a number!");
System.out.println("Enter a NUMBER at the prompt to guess.");
System.out.println("Enter [S] at the prompt to display the summary report.");
System.out.println("Enter [Q] at the prompt to Quit.");
System.out.print("> ");
// Read and execute commands
while (true) {
// Prompt user to enter a command
SimpleIO.prompt("Enter command (NUMBER, S, or Q): ");
String command = SimpleIO.readLine().trim();
// Determine whether command is "E", "S", "Q", or
// illegal; execute command if legal.
int tries = 0;
int round = 0;
int randomInt = 0;
int number = Integer.parseInt(command);
if (number >= 0 && number <= 100) {
if(randomInt == number){
System.out.println("Congratulations! You have guessed correctly." +
" Summary below");
round++;
}
else if(randomInt < number)
{
System.out.println("your guess is TOO HIGH. Guess again or enter Q to Quit");
tries++;
}
else if(randomInt > number){
System.out.println("your guess is TOO LOW. Guess again or enter Q to Quit");
tries++;
}
} else if (command.equalsIgnoreCase("s")) {
// System.out.println("Round Guesses");
// System.out.println("-------------------------");
// System.out.println(round + "" + tries);
} else if (command.equalsIgnoreCase("q")) {
// Command is "q". Terminate program.
return;
} else {
// Command is illegal. Display error message.
System.out.println("Command was not recognized; " +
"please enter only E, S, or q.");
}
System.out.println();
}
}
}
You should check for the S/Q value first, then parse the string to an integer. If you catch NumberFormatException (thrown by Integer.parseInt()), you can determine if the input is a valid value. I would do something like that:
if ("s".equalsIgnoreCase(command)) {
// Print summary
} else if ("q".equalsIgnoreCase(command)) {
// Command is "q". Terminate program.
return;
} else {
try {
Integer number = Integer.parseInt(command);
if(number < 0 || number > 100){
System.out.println("Please provide a value between 0 and 100");
} else if(randomInt == number){
System.out.println("Congratulations! You have guessed correctly." +
" Summary below");
round++;
} else if(randomInt < number) {
System.out.println("your guess is TOO HIGH. Guess again or enter Q to Quit");
tries++;
} else if(randomInt > number) {
System.out.println("your guess is TOO LOW. Guess again or enter Q to Quit");
tries++;
}
} catch (NumberFormatException nfe) {
// Command is illegal. Display error message.
System.out.println("Command was not recognized; " +
"please enter only a number, S, or q.");
}
}
With this algorithm (I'm sure it can be optimized), you treat following cases:
User enters s/S
User enters q/Q
User enters a non valid value (not a number)
User enters a non valid number (less than 0 or greater than 100)
User enters a valid number
To check if a string is an integer, just attempt to parse it as an integer and if an exception is thrown, then it is not an Integer.
See:
http://bytes.com/topic/java/answers/541928-check-if-input-integer
String input = ....
try {
int x = Integer.parseInt(input);
System.out.println(x);
}
catch(NumberFormatException nFE) {
System.out.println("Not an Integer");
}
Integer.parseInt(command) will give you NumberFormatException if the String is not valid. It is possible in your code if the user enters 'S' or 'E' which cannot be parsed to int value.
I have modified your code. Check this code :
while (true) {
// Prompt user to enter a command
SimpleIO.prompt("Enter command (NUMBER, S, or Q): ");
String command = SimpleIO.readLine().trim();
// Determine whether command is "E", "S", "Q", or
// illegal; execute command if legal.
int tries = 0;
int round = 0;
int randomInt = 0;
if(!command.equals("S") && !command.equals("E")) {
// Only then parse the command to string
int number = Integer.parseInt(command);
if (number >= 0 && number <= 100) {
if(randomInt == number){
You're trying to convert the incoming String to an int before you check if its an escape sequence (S or Q).
Try rearranging your if statement to check for S and Q first then try converting the value to an int.
I'd also recommend you wrap the Integer.parseInt call (it's subsequent, reliant code) in a try-catch block, so you can provided an error statement to the user if they type in anything that isn't an int