This is my first Java program. The assignment is to create a program as follows:
Develop a Java program that works as follows:
1). When the program is started, it displays a message welcoming the player: "Welcome to Game Guru!"
2). Then it creates a secret random number between 1 and 20;
3), Then it displays a message saying: "Guess my magic number [1-20]: "
4). Read and check the number entered by the player.
If is not a number, the program displays a message saying: "Should enter a number". then go back to step 3)
If the number is out of range, the program displays a message saying: "Number out of range". Then go back to step 3)
If the number is smaller than the secret number, the program displays a message saying: "Number too small". Then go back to step 3)
If the number is greater than the secret number, the program displays a message saying: "Number too large". Then go back to step 3)
If the number is the same as the secret number, the program displays a message saying: "You got it!". Then go to step 5)
5). The program displays a message saying: "Want more games?"
6). Read the player's answer. If the answer is "yes", then to step 1); If the answer is "no", then go to step 7)
7). The program displays message "Thanks for playing the game. Goobye".
I have gotten it working completely EXCEPT when entering anything other than an INT it gives an exception. I tried researching this myself and found the Try/Catch but it doesn't seem to be working for me. My instructor wont help me...despite the fact that he hasn't actually taught any of this...
Here's my code:
public static void main(String[] args)
{
// TODO Auto-generated method stub
String more;
do
{
System.out.println("Welcome to Game Guru!");
int number = 1 + (int)(Math.random() * 20);
int guess = 0;
Scanner input = new Scanner(System.in);
try
{
System.out.println("Guess my magic number [1-20]: ");
guess = input.nextInt();
}
catch (Exception e)
{
System.out.println("Should enter an integer");
}
while (guess != number)
{
if (guess > 20 || guess < 1)
{
System.out.println("Number out of range");
System.out.println("Guess my magic number [1-20]: ");
guess = input.nextInt();
}
else if (guess < number)
{
System.out.println("Number too small");
System.out.println("Guess my magic number [1-20]: ");
guess = input.nextInt();
}
else if (guess > number)
{
System.out.println("Number too large");
System.out.println("Guess my magic number [1-20]: ");
guess = input.nextInt();
}
}
if (guess == number)
{
System.out.println("You got it!");
}
System.out.println("Want more games? Please enter Y or N.");
more = input.next();
} while (more.equals("y") || more.equals("Y"));
System.out.println("Thanks for playing the game. Goodbye");
}
}
Here's the console:
Welcome to Game Guru!
Guess my magic number [1-20]:
a
Should enter an integer
Number out of range
Exception in thread "main" java.util.InputMismatchException
at java.base/java.util.Scanner.throwFor(Unknown Source)
at java.base/java.util.Scanner.next(Unknown Source)
at java.base/java.util.Scanner.nextInt(Unknown Source)
at java.base/java.util.Scanner.nextInt(Unknown Source)
Guess my magic number [1-20]:
at Game.main(Game.java:46)
I really appreciate any insight into this. I'm at my wits end...I should be paying Google my tuition.
So, starting with...
try
{
System.out.println("Guess my magic number [1-20]: ");
guess = input.nextInt();
}
catch (Exception e)
{
System.out.println("Should enter an integer");
}
Basically, if an exception occurs, the Scanner still contains non-numerical data in it's buffer, this means that if you then try and read the buffer again, doing something like...
guess = input.nextInt();
You will get the same exception again.
A general solution is to call input.nextLine() to clear the buffer before attempting to read new data from it. Personally, I'd use nextLine for all the inputs and Integer.parseInt to parse those elements which you want as int values, but that's me.
Since you have to ask the user for input each time they need to make a guess, you could simplify your solution by using a do-while loop instead (you have to enter the loop at least once any way), this way you could get the input, verify the value (as an int) and perform your required logic on it, all within a single basic loop...
Scanner input = new Scanner(System.in);
String more = "N";
do {
System.out.println("Welcome to Game Guru!");
int number = 1 + (int) (Math.random() * 20);
int guess = 0;
do {
try {
System.out.println("Guess my magic number [1-20]: ");
String text = input.nextLine();
guess = Integer.parseInt(text);
if (guess > 20 || guess < 1) {
System.out.println("Number out of range");
} else if (guess < number) {
System.out.println("Number too small");
} else if (guess > number) {
System.out.println("Number too large");
}
} catch (NumberFormatException e) {
System.out.println("Should enter an integer");
}
} while (guess != number);
System.out.println("You got it!");
System.out.println("Want more games? Please enter Y or N.");
more = input.nextLine();
} while (more.equalsIgnoreCase("y"));
In the try, you are giving the code you want to execute (fine). In the except statement, you are correctly printing out the error too (great).
Unfortunately, you didn't fix it!
It probably makes sense to put your try/catch in a while loop that repeats until you get valid input. That way, once it works, you move on to the rest of your logic which is dependent on getting valid input from the user in the try/catch.
You're asking to enter an int, if the user enter another value as a String or Float you will get an exception.
Add another try{} catch{} block to verify if it is an Integer otherwise cast it
What happens in your code is that it catches that exception in the first try/catch, prints System.out.println("Should enter an integer"); and then proceeds to the rest of the do block. You need to continue after printing that message.
However, you'll encounter more bugs in that code as you continue testing, this is just to answer your question about that exception.
The purpose of your try/ catch is to tell the user that the number they selected is not an integer. The program is not supposed to continue if you enter something other than an integer, as it says in step 4- The first if statement is used to verify that the number is an integer.
Instead, you are using a try/ catch, which also stops the program, but a little differently.try/catch block
The block of code in the try statement prompts the user to enter a number 1-20. If it is not, it throws the exception because the number entered is not an integer. It prints the message " Should enter an integer", and prints out the errors that should tell the user what is wrong. It is telling you there is an error in the Main class of your program, and where the problem is located. The purpose of the print statement " Should enter an integer" was to prompt the user to enter an integer the next time the program runs, so the program can then run correctly.
In your case, the if statement would make more sense to use. Again, the only point of this block of code is to verify the user has entered an integer.
Related
I have a problem with my program is not with the code is how I am going to do it that's the confusing part that I am stuck with. just to let you know I am a basic java coder I do not understand complicated stuff so bear in mind that my code isn't the best.
----------------------------------------------------------- program explaintion-----------------------------------------------------------------
let's get into the point of explaining how it works before I show you my problem, ok when you execute the program it prompts you a sort of like a menu in a video game but it's a text-based, it shows you different options like enter player details, play the math game show score and then quit. enter player details it tells player 1 to enter he/she name and then tells another one to input he/she player name then prompts you back to the menu. play the math game is where a player 1 is asked to input he/she math equation after that player 2 has to solve it if he gets it right he gets 10 points if no the player gets no points at all. then repeats for another player to input he/she math equation then prompts you back to the menu. show scores it shows who got the most scores in the math game it calculates who's got the most if both of them got the same score then means a tie then prompts you back to the menu. and the last thing the quit option when you choose that option it stops the program. if the player chooses a wrong choice he gets an error message and puts you back to the menu
ok here is the first class called menu and other class which is connected with menu called game factions
menu:https://gist.github.com/LOLMEHA/86ff28b038d85030e346785e953644e0
gamefactions:https://gist.github.com/LOLMEHA/f05a51e07c8823a0e65cebbf81cc52ef
so this section of code that I have trouble fingering it out myself
import java.util.*;
public class Gamefunctions // this is a core when player choosess one of these options from the menu
{
String[] player =new String[2];
double scorea = 0; // verribles of all the objects
double scoreb = 0;
int i;
Scanner input = new Scanner(System.in);
double answer = 0;
double numA, numB;
char operator;
char operator2;
boolean quit = false;
double sum1;
double sum2;
public void enterDetails(){ // if player select enter details
for ( i=0;i<2;i++) {// tell's player to input he/she's name and stores them
int c=i;
System.out.println("Welcome to the maths quiz game please input player name "+c++);
player[i] = input.next();
}
}
public void mathGame(){ // if player select enter details
System.out.println("Please enter your equation please "+player[0]+" press enter for each number and mathematical symbol"); // tells the player 1 to input
System.out.println("");
System.out.println("such as for ex input a number or how many you like, then hit enter and input such as /*-+^ hit enter, then input any number one or how many you like ");
String s=input.next();
numA = Double.parseDouble(s); // numa and numb and operator is the aera of player to input he/she equation
operator = input.next().charAt(0);
numB = input.nextDouble();
if () {
if (operator == '+') {// this is if operator is one of these like +-*/^ and then it works out the sum
answer = numA + numB;
}
if (operator == '-') {
answer = numA - numB;
}
if (operator == '*') {
answer = numA * numB;
}
if (operator == '/') {
answer = numA / numB;
}
if (operator == '^') {
answer = Math.pow(numA, numB);
}
} else {
System.out.println("error input like for an example '10' enter '+' enter '10'");
}
System.out.println("");
System.out.println(player[1]+"\t solve the equation"); // tells other player to slove the equation
sum2 = input.nextDouble();
if (sum2 == answer){// checks if the answer from the player is good or not if its good he/she gets 10 points if he/she gets it wrong gets no points and shows the right answer so the player learns from his/she mistakes
scoreb = scoreb + 10.00;
System.out.println("correct you got 10 points to your score");
System.out.println("");
} else{
System.out.println("incorrect you got no points the correct answer was:"+"" + answer);
}
you know when the program ask to player to input his math eqtion and outputs this and continues with the program and waiting for the user to input
public void mathGame(){ // if player select enter details
System.out.println("Please enter your equation please "+player[0]+" press enter for each number and mathematical symbol"); // tells the player 1 to input
System.out.println("");
System.out.println("such as for ex input a number or how many you like, then hit enter and input such as /*-+^ hit enter, then input any number one or how many you like ");
String s=input.next();
numA = Double.parseDouble(s); // numa and numb and operator is the aera of player to input he/she equation
operator = input.next().charAt(0);
numB = input.nextDouble();
let's say that the player inputs like this 10+10 enter but it will not work since they are stored in numA which is an int, I want to make a error message saying that you can not input like this 10+10 you have to input like this 10 enter + enter 10 enter so it will be able to work
if the player inputs it correctly it will continue the program
so if you have any problems with my explaintion of my plroblem pls ask so I can edit it thank you for time :)
Here’s the bit of your code I’m going to be looking at:
String s = input.next();
numA = Double.parseDouble(s);
operator = input.next().charAt(0);
numB = input.nextDouble();
if (/* Some condition */) {
// Calculate answer
} else {
System.out.println("error input like for an example '10' enter '+' enter '10'");
}
First up, a couple nitpicks: Java is not C. You don’t need to declare all your variables at the beginning of your code blocks. numA, numB and operator are never used outside this bit of code, so it makes sense to declare them in here as well.
You’re also using input.next() with Double.parseDouble() once, then input.nextDouble() the next time. Stick to one or the other, it’ll make debugging easier if something doesn’t work properly.
And finally, what happens if someone enters 10 +1 0? The error is silently ignored because the 1 gets picked up as part of the operator string then discarded by charAt(0). A more resilient parsing method here would be to fetch the entire String first, then check for length == 1 before calling charAt(0).
double numA = input.nextDouble();
String operatorString = input.next();
char operator;
if (operatorString.length() == 1) {
operator = operatorString.charAt(0);
} else {
// Handle error
}
double numB = input.nextDouble();
if (/* Some condition */) {
// Calculate answer
} else {
System.out.println("error input like for an example '10' enter '+' enter '10'");
}
Onto your question then: how do we detect an invalid input? Take a look at the documentation for Scanner#nextDouble() (emphasis mine):
public double nextDouble()
Scans the next token of the input as a double. This method will throw InputMismatchException if the next token cannot be translated into a valid double value. If the translation is successful, the scanner advances past the input that matched.
So we know nextDouble() can detect the invalid input for us. It does this in the form of an exception, which we can listen for (or catch) using a try ... catch statement:
try {
double numA = input.nextDouble();
} catch (InputMismatchException e) {
System.err.printf("Invalid input! Expected number, found '%s'.\n", input.next());
}
We could extend this and wrap the entire section of code in a single try ... catch, but then the user would have to start again if they make one mistake. A more user-friendly solution would be this:
double numA;
while (1) {
try {
numA = input.nextDouble();
break;
} catch (InputMismatchException e) {
System.err.printf("Invalid input, try again! Expected number, found '%s'.\n", input.next());
}
}
Note the even if you don’t print it, the call to input.next() is necessary to prevent an infinite loop.
Now we just need to do something similar for operator:
char operator;
while (1) {
String operatorString;
try {
operatorString = input.next();
if (operatorString.length() != 1) {
throw new InputMismatchException();
}
operator = operatorString.charAt(0);
break;
} catch (InputMismatchException e) {
System.err.printf("Invalid input, try again! Expected character, found '%s'.\n", operatorString);
}
}
This seems very similar to the previous snippet for a number - let’s try to refactor some of the common code here into a method:
#FunctionalInterface
public interface ScannerGetter<T> {
T apply() throws InputMismatchException;
}
public <T> T getValueFromScanner(ScannerGetter<T> getter, String type) {
while(1) {
try {
return getter.apply();
} catch (InputMismatchException e) {
System.err.printf("Invalid input, try again! Expected %s.");
}
}
}
There’s a lot going on in these few lines. The first part declares a functional interface - this is a basically a custom type of lambda function. We’ll come back to that in a moment.
The method itself (getValueFromScanner()) is a generic method. It allows us to use the same method with different types in place of the generic parameter (T) without duplicating it.
This is how you’d use the above method to retrieve your three inputs:
double numA = this.<Double>getValueFromScanner(() -> input.nextDouble(), "number");
char operator = this.<Char>getValueFromScanner(() -> {
operatorString = input.next();
if (operatorString.length() != 1) {
throw new InputMismatchException();
}
return operatorString.charAt(0);
}, "operator");
double numB = this.<Double>getValueFromScanner(() -> input.nextDouble(), "number");
// Once your code gets here, all three variables will have valid values.
After catching an exception, how do I continue the execution of a Java program?
I made a program that asks a user to enter a number and it will return that number divided by a random number generated. However, if the user enters a letter like 'a', an exception will be caught.
How do I make the program continue its execution instead of terminating after it catches the exception?
do{ //Begin of loop
try{ //Try this code
System.out.println("Enter a number");
double i = read.nextDouble(); //Reads user input
double rn = r.nextInt(10); //Generates random number rn
System.out.println(i + " divided by random number " + rn + " is " + (i/rn));
}catch(InputMismatchException type_error){ //Catches error if there is a type mismatch
//Example error: if user enters a letter instead of a double
System.out.println("Error. You cannot divide a letter by a number!");
break; //break stops the execution of the program
}
//using a continue statement here does not work
}while(true); //Loop forever
Continue won't help! If you use Scanner class to input the numbers, you got an infinite loop writing "Error. You cannot divide a letter by a number!" to the output.
Your code waits for a double number, but got a letter. This event triggers an exception, the code displays the error message. But the letter will remains in the scanner, so the nextInt command tries to load the same letter in the next iteration, without wait for you typing.
In the catch block, you have to empty the scanner with a read.next() command.
Scanner read = new Scanner(System.in);
Random r = new Random();
do { //Begin of loop
try { //Try this code
System.out.println("Enter a number");
double i = read.nextDouble(); //Reads user input
double rn = r.nextInt(10); //Generates random number rn
System.out.println(i + " divided by random number " + rn + " is " + (i / rn));
} catch (InputMismatchException type_error) { //Catches error if there is a type mismatch
//Example error: if user enters a letter instead of a double
System.out.println("Error. You cannot divide a letter by a number!");
// Empty the scanner before the next iteration:
read.next();
}
//using a continue statement here does not work
} while (true); //Loop forever
The continue statement will restart the loop (as opposed to the break statement, which terminates the loop).
As such if you replace break; with continue;, you will keep on looping after your Exception is caught (providing no other Exception is thrown but the one caught), ans the error message is displayed.
Essentially it will print "Enter a number" again, etc.
Warning
You also need to consume the Scanner's next value.
If you don't, using continue will loop forever with no user interaction when an error occurs.
Example
Scanner read = new Scanner(System.in);
do {
try {
// trimmed out non-necessary stuff
System.out.println("Enter a number");
double i = Double.parseDouble(read.nextLine());
System.out.println(i);
// changed exception caught
}
catch (NumberFormatException type_error) {
System.out.println("Error. You cannot divide a letter by a number!");
continue;
}
} while (true);
Final note
As mentioned by Berger, continue here is not even necessary because you are only printing a warning message.
The break statement is causing the end of the loop.
The break statement has two forms: labeled and unlabeled. You saw the
unlabeled form in the previous discussion of the switch statement. You
can also use an unlabeled break to terminate a for, while, or do-while
loop
Solution :
Change it to continue.
The continue statement skips the current iteration of a for, while ,
or do-while loop.
The break statement causes the loop to exit. Since you have no code in the loop after the try-catch construct, you can simply remove the break statement.
Note that the Scanner method (I assume read is a Scanner) nextDouble() returns the double value if the next token represents a double. If not, it throws an exception without consuming that token. So you need to ensure you consume the next value, which you can do with read.next():
do{ //Begin loop
try{ //Try this code
System.out.println("Enter a number");
double i = read.nextDouble(); //Reads user input
double rn = r.nextInt(10); //Generates random number rn
System.out.println(i + " divided by random number " + rn + " is " + (i/rn));
}catch(InputMismatchException type_error){ //Catches error if there is a type mismatch
//Example error: if user enters a letter instead of a double
System.out.println("Error. You cannot divide " + read.next() + " by a number!");
}
} while(true);
One more solution is just replace break with read.nextLine();.
break statement is causing the end of the loop.
continue will prints Enter a number again and again.
But read.nextLine();, code will asks the input again and again.
If you remove read.nextLine(); or continue, code will prints Enter a number again and again.
Just remove the break; from there, and everything will work fine.
Remember however to put a termination condition, i don't see it anywhere.
I am having problems with my program. Everything is running smoothly, however, when the user inputs the wrong variable it does display the right feedback, but the user then has to enter one extra variable than previously stated.
Maybe it's a simple mistake I have made, but I can't see it..
It's confusing. An example when I run the program:
How many grades would you like to average?
3
Please enter 3 grades:
90
jf //Intentional user input error
You've entered a non-numerical variable. Please enter a number:
95
100 //The program should go ahead and calculate the average after this is entered
100 //It should not expect this fourth input if the amount of grades is 3
Your average is: 96.67
The second 100 input in the console should not appear, but it does when the user has at least one input error. If I were to run the program and input all the correct variables, then the program works smoothly.
This error also occurs when asking for how many grades the user would like to average. I thought it'd be easier to view what's wrong with my program by the second part.
I'm trying to get this program to run smoothly. Help is appreciated!
for (gradesCount = 0; gradesCount < gradeNumber; gradesCount++) {
// Check if the input variables are numerical variables
while (!input.hasNextDouble()) {
input.next();
System.out.println("You've entered a non-numerical variable. Please enter a number: ");
while (input.nextInt()<= 0){
System.out.println("You've entered a negative number. Please eneter a positive number: ");
}
}
// Read grade input
gradesInput = input.nextDouble();
Instead of input.hasNextDouble() you can try below
Scanner scan = new Scanner(System.in);
System.out.print("Enter total no of input ");
int total = Integer.parseInt(scan.nextLine());
int[] input = new int[total];
for (int i = 0; i < total; i++) {
while (true) {
try {
System.out.print("Enter number ");
String in = scan.nextLine();
input[i] = Integer.parseInt(in);
break;
} catch (RuntimeException re) {
System.err.print("Invalid input. ");
}
}
}
scan.close();
System.out.println(Arrays.toString(input));
It'll force the user input only numbers, you can add boundaries or change data type if required.
boolean acceptPcode=true;
boolean acceptQty=false;
int Qty=0;
List<Integer> purchasedProdQty=new ArrayList<>();
while(acceptPcode==true && acceptQty==false){
do{
try{
System.out.print("Enter Qty: ");
Qty=sc.nextInt();
acceptQty=true;
}catch(InputMismatchException ime){
System.out.println("Invalid quantity please enter a number!");
acceptQty=false;
}
if(acceptQty==true)
purchaseProdQty.add(Qty);
}while(acceptQty==false);
}
my question is that when i enter a letter it goes in an infinity loop and it doesn't prompt the user to enter a quantity ....which is
Enter Qty: Invalid quantity please enter a number!
Enter Qty: Invalid quantity please enter a number!
Enter Qty: Invalid quantity please enter a number!......
You forgot to read the \n (or \r\n) characters that are from the next line. In your current code, the scanner is waiting for an int input, bu the current next input is this break line char. Just add sc.nextLine() in your code to consume the break line char:
Qty=sc.nextInt();
sc.nextLine();
acceptQty=true;
From what I can gather it seems your scanner(sc) is throwing an exception. This causes acceptQty to constantly be false keeping you stuck in your inner do-while loop.
You need to consume any illegal characters in the exception block otherwise they won't be consumed by the Scanner#nextInt method call causing the loop to repeat itself indefinitely:
} catch(InputMismatchException ime) {
System.out.println
("Invalid quantity: " + sc.nextLine() + " please enter a number ");
...
}
You are getting exception while reading out of sc and so it always go into infinity loop. Can you paste what's the value assiged in sc?
I believe you're doing this all wrong. Your method of validation is very obscure and can be simplified. Suppose you have the following method:
public int readNumber(final String prompt, final Scanner scanner){
System.out.println(prompt);
try{
return scanner.nextInt();
}catch(Exception ex){
System.err.println("Enter a valid number");
return readNumber(prompt, scanner);
}
}
This method will print out the prompt (the first argument) and read input from the provided Scanner (the second argument). If the user enters something that can't be parsed as an int, it will invoke the same method (recursion).
Take out both of your loops and when you want to read an int from your Scanner, do something like:
int value = readNumber("Enter a quantity", sc);
You know for sure that Integer.MAX_VALUE >= value >= Integer.MIN_VALUE
I wrote a program to determine a prime number and am required to use 'Q' as the quit function to get out of the program. Below is the code i have written. I am wondering how I would modify method of quitting the program to make it exit correctly.
import java.util.Scanner;
public class Practice
{
public static void main(String[]args)
{
Scanner keyboard = new Scanner(System.in);
int number, i=2;
String quit;
boolean prime = true;
System.out.println("Please enter a number to determine if it is prime, to quit please enter Q.");
number = keyboard.nextInt();
quit = keyboard.nextLine();
for (i=0; i<number;i++)
{
if ((number%2==0) || (number==1) || (number%3==0))
{
prime = false;
}
}
if (prime==false)
{
System.out.println(number+" is not a prime number.");
}
else if(prime==true)
System.out.println(number+" is a prime number.");
if (quit.charAt(0)=='Q')
{ System.exit(0);}
and my output upon entering 'Q' is:
----jGRASP exec: java Practice
Please enter a number to determine if it is prime, to quit please enter Q.
Q
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:909)
at java.util.Scanner.next(Scanner.java:1530)
at java.util.Scanner.nextInt(Scanner.java:2160)
at java.util.Scanner.nextInt(Scanner.java:2119)
at Practice.main(Practice.java:15)
----jGRASP wedge2: exit code for process is 1.
----jGRASP: operation complete.
}
}
When the input through the console is given as "Q", the value of type String is getting assigned to a variable of type int, which is incorrect.
number = keyboard.nextInt();
The type of in the input needs to be checked, before it can be assigned to a int variable.
You have:
number = keyboard.nextInt();
quit = keyboard.nextLine();
Think for a moment about what actually happens here. 'Q' is not a number and so nextInt(), as documented, throws an InputMismatchException. Your use of nextLine() doesn't make much sense following that.
You have a couple of options:
Use Scanner.hasNextInt() to determine if the next token truly is a well-formed integer. If not, read it as a string and check it.
Use Scanner.next() always, and check if it is "Q" before parsing it with Integer.parseInt() (being prepared to handle errors there as well).
The Scanner.next* functions don't implicitly skip invalid values. The Scanner is only doing what you tell it to do, and if you tell it to grab an integer but the input is not an integer, it rightfully complains. It is up to you to use the Scanner appropriately and check your possible input cases.
You should read in the numbers as Strings with keyboard.nextLine();
and check first if the it contains 'Q'. If it does, quit, else do, number = Integer.parseInt(yourVariableHere); and go from there
Try this instead:
String input;
int number = 1;
int i=2;
Then do this:
System.out.println("Please enter a number to determine if it is prime, "
+ "\nto quit, please enter Q.");
input = keyboard.nextLine();
if (input.charAt(0)=='Q')
{
System.exit(0);
}
else
{
try
{
number = Integer.parseInt(input);
}
catch(NumberFormatException nfe)
{
System.out.println("Please enter a number or Q!");
}
}