Introduction
The code I am going to present now is part of a loop for a game. I am having problems with a error handling (not through exceptions).
Problem
This next function takes 4 int variables (row_1, col_1, row_2, col_2) which have to be checked if they are less than (size-1).
The reason behind is that we are working with a matrix and the range is from 0 to (size-1).
So if the user inputs less than 0 or more than (size-1) it should be asking again for an input
Code
public static void gameLoop()
{
//While you still play (true) or if (false) -> end game
showMatrix(gameMatrix);//Cheat
while(play == true)
{
showMatrix(displayMatrix);
System.out.println("--------------------");
System.out.println("Input first row and col press enter between inputs");
System.out.print("First row: ");
row_1 = scan.nextInt();
System.out.print("First column: ");
col_1 = scan.nextInt();
System.out.println("Input second row and col press enter between inputs");
System.out.print("Second row: ");
row_2 = scan.nextInt();
System.out.print("Second column: ");
col_2 = scan.nextInt();
if (row_1 == row_2 && col_1 == col_2)
{
System.out.println("I tested this!");
showMatrix(displayMatrix);
System.out.println("--------------------");
System.out.println("[ERROR] Input not valid! Try again");
System.out.println("Input first row and col press enter between inputs");
System.out.print("First row: ");
row_1 = scan.nextInt();
System.out.print("First column: ");
col_1 = scan.nextInt();
System.out.println("Input second row and col press enter between inputs");
System.out.print("Second row: ");
row_2 = scan.nextInt();
System.out.print("Second column: ");
col_2 = scan.nextInt();
}
else if ((row_1 > size || row_1 < 0) && (row_2 > size || row_2 < 0) && (col_1 > size || col_2 < 0) && ((col_2 > size || col_2 < 0)))
{
System.out.println("I tested that!");
showMatrix(displayMatrix);
System.out.println("--------------------");
System.out.println("[ERROR] Input not valid! Try again");
System.out.println("Input first row and col press enter between inputs");
System.out.print("First row: ");
row_1 = scan.nextInt();
System.out.print("First column: ");
col_1 = scan.nextInt();
System.out.println("Input second row and col press enter between inputs");
System.out.print("Second row: ");
row_2 = scan.nextInt();
System.out.print("Second column: ");
col_2 = scan.nextInt();
}
Turn(row_1, col_1, row_2, col_2, gameMatrix);
check = checkEndgame(gameMatrix, displayMatrix);
if(check == false)
{
System.out.println("Would you like to play again? Y/N");
game_option = scan.next();
if ("Y".equals(game_option) || "y".equals(game_option))
{
createGame();
gameLoop();
}
else if ("N".equals(game_option) || "n".equals(game_option))
{
play = false;
}
}
}
}
Part of the code with the problem
if (row_1 == row_2 && col_1 == col_2){}
else if ((row_1 > size || row_1 < 0) && (row_2 > size || row_2 < 0) && (col_1 > size || col_2 < 0) && ((col_2 > size || col_2 < 0))){}
Question
I do not understand where I did go wrong with this logic after testing numbers which should trigger it.
Notes
Feel free to judge the code and help me with design or error handling
Those System.out.println("I tested that!"); && System.out.println("I tested this!"); are debug stdout.
Suggestions:
Console applications are unforgiving and unless handled carefully at the development stage can lead to an application no one wants to use because of its inability to handle input Errors or simple typing mistakes. How many times are you willing to restart an application.
People do make entry mistakes and the more informative your application is the less mistakes a User will make. For example, if you only want Users to input a value from 0 to let's say 10 then let them know what the requirements are, constantly:
Please enter the numerical values for FIRST Row and Column:
First Row (0 to 10): 7
First Column (0 to 10): |
You will always need to validate input so as to ensure that what is provided will actually process without any errors being generated. As you well know the keyboard is a pretty big input device with an awful lot of buttons on it and any one of then can be accidentally struck during input without the User even being aware of it. After all, everyone that owns a keyboard is automatically a typing master and can pump out 400 words per minute without looking at the screen. Well....so it seems and to be quite honest, I'm am by no means any exception to that.
Allow the User to carry out a re-entry should an error occur. Don't be afraid to utilize while loops for this, even nested ones. If handled correctly, there will be no issues with them.
Although this portion of your application is small, allow the User to quit at any time unless of course the current point needs to be completed in order to accomplish a clean exit. It's nasty when you can't get out of an application unless you finish it. especially when you just don't want to.
Where you can, use Methods or Classes to reduce or eliminate code duplication. Sometimes it is easier to read code when its long and drawn out with lots of duplication but in most cases it doesn't take long to get sick of looking at it. It can make you dizzy after a while. The old excuse "I just do it to get it working then I clean it up" really doesn't fly, well for the most part. If you can eliminate code duplication right away that way you don't have to code your application twice...or three times...or maybe more. Yes, we all do it in one form or another and again, I'm no exception to this.
By removing most code duplication and adding a small method or two your particular code segment might look something like this:
Scanner scan = new Scanner(System.in); // Declare Scanner (here for sake of this demo)
String LS = System.lineSeparator(); // System line Separator.
boolean play = true; // Play flag
int size = 8; // 8 is used for sake of this demo
String range = "(0 to " + (size - 1) + ")"; // Range so we don't have to keep typing it.
String[] rowCol; // Array to hold Row and Column string numerical values
String border1 = String.join("", Collections.nCopies(72, "-")); // Text Border 1 (-)
String border2 = String.join("", Collections.nCopies(42, "=")); // Text Border 2 (=)
while (play) {
String input = ""; // Input from scanner goes in this variable
rowCol = new String[4]; // Initialize Array
// Declare & init int variables to hold input integer values (if desired)
// Un-comment the below line if you want this...
// int row_1 = -1, col_1 = -1, row_2 = -1, col_2 = -1;
// Inform of what is required...
System.out.println(border1);
System.out.println("Please enter the numerical values for FIRST and "
+ "SECOND Rows and Columns." + LS + "Follow the provided prompts. "
+ "You can Enter 'q' or 'quit' at any time to" + LS + "end the game.");
System.out.println(border1);
// Get Input from User
for (int i = 0; i < rowCol.length; i++) {
// Set up current prompt...
String prompt = LS;
switch (i) {
case 0:
prompt += "Enter First Row Value " + range + ": ";
break;
case 1:
prompt += "Enter First Column Value " + range + ": ";
break;
case 2:
prompt += "Enter Secomd Row Value " + range + ": ";
break;
case 3:
prompt += "Enter Second Column Value " + range + ": ";
break;
}
input = ""; // Clear input variable
// Get the actual input from User and validate.
while (input.equals("")) {
System.out.print(prompt); // Display prompt
input = scan.nextLine(); // Get keyboard input from User
// Validate input...
if (!validateUserRowColInput(0, (size - 1), input)) {
input = ""; // Input was invalid so clear input variable
continue; // Re-prompt the User for proper input
}
rowCol[i] = input; // All is good so add input to Array element at index i.
}
}
// Display what was provided.
System.out.println(border2);
System.out.println("Row 1/Column 1 = " + rowCol[0] + "/" + rowCol[1] + LS
+ "Row 2/Column 2 = " + rowCol[2] + "/" + rowCol[3]);
System.out.println(border2 + LS);
}
The rest of your game loop code you can add yourself. In the above code a simple String Array (named rowCol) is utilized to hold the values supplied by a User. This allows us to use a single for loop nested within the main play while loop to prompt for all 4 inputs from the User therefore eliminating some duplicate code and carrying out input validation all in one house so to speak.
If you want to convert the inputs to Integer (int's) then you could do something like this instead (directly after the for loop):
/* Array index 0 and 1 now contains the string numerical
values for First Row and First Column. Array index 2 and
3 now contains the string numerical values for Second Row
and Second Column. If you just can't wrap your head around
dealing with Arrays and indexes from this point then do
something like the following: */
// Convert String Array elements to integers
row_1 = Integer.parseInt(rowCol[0]);
col_1 = Integer.parseInt(rowCol[1]);
row_2 = Integer.parseInt(rowCol[2]);
col_2 = Integer.parseInt(rowCol[3]);
// Display what was provided.
System.out.println(border2);
System.out.println("Row 1/Column 1 = " + row_1 + "/" + col_1 + LS
+ "Row 2/Column 2 = " + row_2 + "/" + col_2);
System.out.println(border2 + LS);
The validateUserRowColInput() method which as it implies, validates the Users input to respect the desired rules for the code segment above. It is called directly after the User supplies input. The validation rules are basically what you had laid out within your post and the validation is done upon each input supplied rather than waiting for all four inputs to be provided:
Validation Rules:
No Blank entries allowed;
Only numerical characters can be supplied, no alpha characters other
than q or the word quit are accepted (not case sensitive);
If q or the word quit is supplied the program ends;
Row 1 and or Row 2 can not be Less Than 0;
Column 1 and or Column 2 can not be less than 0;
Row 1 and or Row 2 can not be Greater Than (size - 1);
Column 1 and or Column 2 can not be Greater than (size - 1);
The User is of course informed if a rule is broken and given the opportunity to make a correct entry. Here is the validateUserRowColInput() method:
/**
* Validates the User's Row and Column values input. This method checks to
* ensure only numerical characters were entered. It also ensures the the
* numerical value entered is between and or equal to the supplied minValue
* and maxValue.
*
* #param minVal (Integer) The minium Allowable integer value to be
* entered.
* #param maxVal (Integer) The maximum allowable integer value to be
* entered.
* #param inputString (String) String representation of the integer value
* supplied.
*
* #return (Boolean) True if the entry is valid and false if it is not.
*/
private static boolean validateUserRowColInput(int minVal, int maxVal, String inputString) {
String LS = System.lineSeparator();
if (inputString.equals("")) {
System.out.println("Invalid Entry! You must supply a numerical "
+ "value from " + minVal + " to " + maxVal + ".");
return false;
}
if (inputString.equalsIgnoreCase("q") || inputString.equalsIgnoreCase("quit")) {
System.out.println("We hope you had fun. Bye Bye");
System.exit(0);
}
if (!inputString.matches("\\d+")) {
System.out.println("Invalid input supplied (" + inputString + ")! "
+ "You can not supply alpha characters, only" + LS
+ "numerical values are allowed!. Please try again...");
return false;
}
int num = Integer.parseInt(inputString);
if (num < minVal || num > maxVal) {
System.out.println("Invalid input supplied (" + inputString + ")! "
+ "The numerical value you supply can not be" + LS + "less "
+ "than " + minVal + " and no greater than " + maxVal + ". "
+ "Please try again...");
return false;
}
return true;
}
Yes....this can all be reduced even more.
You should use a do...while loop to make sure the inputs are valid. It takes a boolean argument:
do {
// All the System.out.println and Scanner stuff...
} while(!checkAnswers(row_1, row_2, col_1, col_2));
Now we have to write the function checkAnswers that will return the boolean to state whether the user is allowed to quit the do...while loop:
public static boolean checkAnswers(int row_1, int row_2, int col_1, int col_2) {
// I don't know why you needed that condition, but I let it there
if(row_1 == row_2 || col_1 == col_2) return false;
// check if the rows and colls are in the range 0...(size - 1)
int[] rowsAndCols = {row_1, row_2, col_1, col_2};
for(int i : rowsAndCols)
if(i < 0 || i >= (size - 1)) return false;
// If everything is good we can quit the do...while loop
return true;
}
Related
In this case, I have asked the user to enter 1,2 or 3. If user enters string, it should ask the question again. when my code runs, every if statement is running, where as I want to run a specific if statement. It would be a huge favor if anyone could help me.
String question = "What is the color of banana? Write 1,2 or 3. Choose one of the following:";
String answerOne = "1. yellow";
String answerTwo = "2. red";
String answerThree = "3. blue";
while(true){
System.out.println(question + "\n" + answerOne + "\n" + answerTwo + "\n" + answerThree);
Scanner input = new Scanner(System.in);
if (input.hasNext()) {
System.out.println("Please select a NUMBER between 1 and 3.");
}
if (input.hasNextDouble()) {
System.out.println("Please select a NUMBER between 1 and 3.");
}
if (input.hasNextInt()) {
int x = input.nextInt();
if (x == 1) {
System.out.println("Congratulations!! your answer is correct");
break;
}
if (x == 2 || x == 3) {
System.out.println("Sorry!! the correct answer is" + answerOne);
break;
}
if (x > 3) {
System.out.println("Please choose the correct answer!!");
}
}
}
}
I think that your problems are as follows.
You create a new scanner each time around the loop
Immediately after the new scanner is created, you execute a couple of 'hasNext' tests. Nothing will have been typed. You're possibly going to spin in that loop forever.
An integer is also a double, so even if the user has typed an integer, it'll satisfy the 'if double' condition.
If an integer is not typed, the input is never read, so you're stuck at that point in the input stream. You'll loop forever.
The flow should look like this:
input = new Scanner();
while (true) {
print question...
try {
int x = input.nextInt(); // waits for user input
process as before;
if (correct answer) {
break out of loop;
}
else {
print "nope";
}
}
catch (InputMismatchException ex) { // something that is not an integer
print "type an integer";
input.nextLine(); // skip incorrect input
}
}
This is just a pseudocode sketch, of course.
It uses exception handling as the most convenient way to make sure an integer is input. By calling nextInt() on the scanner, we assume the user is going to type something that is convertible to integer. The try/catch structure handles the error case.
There are other ways to write this; my own inclination would be to read a line and parse it. But this is closest to what I think was the original intent.
Ok, so first that's not how .hasSomething() works, it used to check if there have more elements. So what you should do, is to read the input as a string and check that string:
String question = "What is the color of banana? Write 1,2 or 3. Choose one of the following:";
String answerOne = "1. yellow";
String answerTwo = "2. red";
String answerThree = "3. blue";
System.out.println(question + "\n" + answerOne + "\n" + answerTwo + "\n" + answerThree);
Scanner input = new Scanner(System.in);
String c = input.next();//read the input
while(!(c.charAt(0) >= '1' && c.charAt(0) <= '3') || c.length() != 1){ //check if it's a number between 1 and 3
System.out.println("Enter agin:");
c = input.next();
}
int x = Integer.parseInt(c);//change c to an integer
if (x == 1) {
System.out.println("Congratulations!! your answer is correct");
break;
}
if (x == 2 || x == 3) {
System.out.println("Sorry!! the correct answer is" + answerOne);
}
i want to make a program reads integers from the user one by one, multiply them and shows the product of the read integers. The loop for reading the integers
stops when the user presses 0. If the user enters a 0 as the first number, then user would not be able to provide any other numbers (Not adding the last 0 in the product). In this case, the program should display “No numbers entered!”
Heres my code right now
ProductNumbers.java
package L04b;
import java.lang.reflect.Array;
import java.util.Scanner;
public class ProductNumbers {
public static void main(String[] args) {
int num = -1;
boolean isValid = true;
int numbersEntered = 0;
int product = -1;
Scanner scnr = new Scanner(System.in);
System.out.println(
"This program reads a list of integers from the user\r\n"
+ "and shows the product of the read integers");
while (num != 0) {
System.out.print("Enter number = ");
int curNum = scnr.nextInt();
if (curNum == 0)
break;
numbersEntered++;
product *= num;
}
if (numbersEntered == 0) {
System.out.println("No numbers entered!");
} else {
System.out.println(product);
}
}
}
I know this is completely wrong, i usually setup a template, try to figure out what needs to be changed, and go by that way, i also need to start thinking outside the box and learn the different functions, because i dont know how i would make it end if the first number entered is 0, and if the last number is 0, the program stops without multiplying that last 0 (so that the product doesnt end up being 0)... i need someone to guide me on how i could do this.
Heres a sample output of how i want it to work
This program reads a list of integers from the user
and shows the product of the read integers
Enter the number:
0
No numbers entered!
and
This program reads a list of integers from the user
and shows the product of the read integers
Enter the number:
2
Enter the number:
-5
Enter the number:
8
Enter the number:
0
The product of the numbers is: -80
You have a nested for loop, why?
You only need the outer while loop that gets the user's input until the input is 0.Also this line:
product *= i;
multiplies i, the for loop's counter to product and not the user's input!
Later, at this line:
if (isValid = true)
you should replace = with ==, if you want to make a comparison, although this is simpler:
if (isValid)
Your code can be simplified to this:
int num = -1;
int product = 1;
int counter = 0;
Scanner scnr = new Scanner(System.in);
System.out.println(
"This program reads a list of integers from the user\r\n"
+ "and shows the product of the read integers");
while (num != 0) {
System.out.print("Enter a number: ");
num = scnr.nextInt();
scnr.nextLine();
if (num != 0) {
counter++;
product *= num;
System.out.println(product);
}
}
if (counter == 0)
System.out.println("No numbers entered");
else
System.out.println("Entered " + counter + " numbers with product: " + product);
One way to solve this is to utilize the break; keyword to escape from a loop, and then you can process the final result after the loop.
Something like this:
int numbersEntered = 0;
while (num != 0) {
int curNum = // read input
if (curNum == 0)
break;
numbersEntered++;
// do existing processing to compute the running total
}
if (numbersEntered == 0)
// print "No numbers entered!
else
// print the result
I think the key is to not try and do everything inside of the while loop. Think of it naturally "while the user is entering more numbers, ask for more numbers, then print the final result"
I want my program to do the certain code only if the actors variable is <=5 && >0
else I want to go back and ask different question again:
System.out.println("\nEnter actors number(max.5): ");
int actorsNumber = scanner.nextInt();
scanner.nextLine();
if (actorsNumber <= 5 && actorsnumber>0) {
for (int i = 1; i <= actorsNumber; i++) {
System.out.println("\nEnter name and surname of the " + i + " actor: ");
String[] parts2 = scanner.nextLine().split("\\s+");
String actName = parts2[0];
String actSurname = parts2[1];
actorName.add(actName);
actorSurname.add(actSurname);
}
}
So when the condition is false for example actors number = 7 then I want to tell the user: "Enter the valid actors number(1-5)" and do the for loop again if the actorsnumber is 1-5 instead ask again "Enter the valid actors number(1-5)"
You need to ask user to enter number in a loop. The condition of the loop will be the condition of your if. Then after exiting the loop (which means user enter a correct number), enter your for loop.
This will look like that :
int actorsNumber = -1; //force a wrong value at the beginning
while(actorsNumber < 1 || actorsNumber > 5) {
//Ask user to enter a number between 1 and 5
//store this number in actorsNumber
}
//As we exited the while-loop, actorsNumber is between 1 and 5
//Put your for-loop here
while(!scanner.nextLine().equals("quit")) {
if (actorsNumber <= 5 && actorsnumber>0) {
for (int i = 1; i <= actorsNumber; i++) {
System.out.println("\nEnter name and surname of the " + i + " actor: ");
String[] parts2 = scanner.nextLine().split("\\s+");
String actName = parts2[0];
String actSurname = parts2[1];
actorName.add(actName);
actorSurname.add(actSurname);
}
}
}
Or something like that, point is, use a while loop on the scanner.
As #apexlol stated, your code should be in a loop. However, do-while loop is more convenient than while loop since that way, the loop executes at least once no matter what.
I've written a portion of code to take a user input, match it to a string value and then use a related double value to make calculations:
double [] currency = new double[] {0.05,0.10,0.20,0.50,1.00,2.00,5.00,10.00,20.00,50.00,100.00};
String [] currencytext = {"$0.05","$0.10","$0.20","$0.50","$1.00","$2.00","$5.00","$10.00","$20.00","$50.00","$100.00"};
Scanner keyboard = new Scanner(System.in);
for (int i = 0; i < currencytext.length; i++) {
boolean valid = false;
while(!valid){
System.out.format("$%.2f remains to be paid. Enter coin or note: ",sum);
String payment = keyboard.next();
if(payment.equals(currencytext[i])){
sum = sum - currency[i];
if(sum == 0) {
System.out.print("You gave " + payment);
System.out.print("Perfect! No change given.");
System.out.print("");
System.out.print("Thank you" + name + ".");
System.out.print("See you next time.");
}
}
if(!(payment.equals(currencytext[i]))) {
System.out.print("Invalid coin or note. Try again. \n");
}
if(payment.equals(currencytext[i]) && currency[i] > sum){
System.out.print("You gave " + payment);
System.out.print("Your change:");
}
}
}
The problem is that when it gets to user input, it doesn't match any string values except for $0.05. It seems to me like its not iterating through the array properly but I can't figure out why. Is anyone able to see a problem here?
This is a possible solution for your problem
Scanner keyboard = new Scanner(System.in);
double [] currency = new double[] {0.05,0.10,0.20,0.50,1.00,2.00,5.00,10.00,20.00,50.00,100.00};
String [] currencytext = {"$0.05","$0.10","$0.20","$0.50","$1.00","$2.00","$5.00","$10.00","$20.00","$50.00","$100.00"};
String payment = keyboard.next();
double sum = 100; // <- Working example - Read sum from keyboard entry
while (sum > 0) {
boolean paymentFound = false;
for (int i = 0; i < currencytext.length; i++) {
if (payment.equals(currencytext[i])) {
sum = sum - currency[i];
paymentFound = true;
if (sum == 0) {
System.out.println("You gave " + payment);
System.out.println("Perfect! No change given.");
// System.out.print("Thank you" + name + ".");
System.out.println("See you next time.");
break;
} else if (sum < 0) {
System.out.println("You gave " + payment);
System.out.println("Your change:" + (-1 * sum));
break;
}
}
}
if (!paymentFound) {
System.out.println("Invalid coin or note. Try again. \n");
}
if (sum > 0) {
System.out.format("$%.2f remains to be paid. Enter coin or note: ", sum);
payment = keyboard.next();
}
}
while-loop will continue until the payment is fullfilled.
for-loop traverse the arrays until a suitable payment is found
If suitable payment is found we substract it from sum. We use break to exit the for-loop in both cases. There is no need to keep searching.
If no suitable payment is found [!paymentFound], we keep on asking.
if (!paymentFound) {
System.out.println("Invalid coin or note. Try again. \n");
}
if (sum > 0) {
System.out.format("$%.2f remains to be paid. Enter coin or note: ", sum);
payment = keyboard.next();
}
The program will end when (sum < 0), in which case the while-loop exits.
I have use println instead of print to improve message legibility.
Too many flaws to point out.
However,
When the currencytext[i] does not match payment, it executes this code:
System.out.print("Invalid coin or note. Try again. \n");
System.out.format("$%.2f remains to be paid. Enter coin or note: ",sum);
payment = keyboard.next();
So, it executes this for all the times that your input does not match currencytext[i].
And, in this block, you have
payment = keyboard.next();
So, it asks for new input, in this block itself. Hence, you get the said output for all inputs except $0.05.
As far as $0.05 is concerned, your first if block executes successfully, and prints no output. So, it moves to the next iteration of the while loop, where again, payment remains the same ($0.05), but currencytext[i] becomes $0.10. SO they do not match, and you get the said output.
How to correct this:
With this code, you need to do a lot of corrections.
I suggest you again start from scratch.
If it doesn't fit, it sets valid to true, so the code just has the chance to check against the first item at currencytext[0], which is $0.05. Then !payment.equals(currencytext[i]) is also true, and your code prints the lines there. Your else ifs are also not properly nested.
I don't know how you are reading input. One improvement you can do is write reading input code in for loop.
Scanner scanner = new Scanner(System.in);
for (... ) {
....
String payment = scanner.nextLine();
....
}
I need help getting this loop to work. It may be because I don't really know how to use loops or the if statements. But I think I needed to use the If statements when it comes to receiving a free yogurt after 10.
import java.util.Scanner;
public class Foothill {
public static void main(String args[]){
Scanner scanner = new Scanner(System.in);
int numPurchases, totalPurchased;
boolean correct;
String menu;
numPurchases = 0;
totalPurchased = 0;
correct = false;
while(!correct)
{
System.out.println("Menu:");
System.out.println(" P (Process Purchase)");
System.out.println(" S (Shut down)");
menu = scanner.nextLine();
if (menu.charAt(0)=='S' || menu.charAt(0)=='s'){
System.exit(0);
} else if (menu.charAt(0)=='P' || menu.charAt(0)=='p'){
continue;
}
System.out.println("Your choice: " + menu.charAt(0));
System.out.println("How many yougurts would you like to buy?");
numPurchases = scanner.nextInt();
totalPurchased += numPurchases;
if (totalPurchased > 0 || totalPurchased < 10){
System.out.println("you have purchased " + totalPurchased + " yogurts");
} else if (totalPurchased >= 10){
System.out.println("Congradulations you have recieve a free Yogurt");
System.out.println("Remainding yogurt credits: " + (totalPurchased-10));
}
}
}
}
I don't really know how to use loops that well so that may be my problem because I have never made a loop using false and true
Just remove the the following statement, then the loop will work:
else if (menu.charAt(0)=='P' || menu.charAt(0)=='p'){
continue;
}
You had a number of problems with your code.
Here is the solution:
import java.util.Scanner;
public class Foothill {
public static void main(String args[]){
Scanner scanner = new Scanner(System.in);
int numPurchases, totalPurchased;
boolean correct;
String menu;
numPurchases = 0;
totalPurchased = 0;
correct = false;
while(!correct){
System.out.println("Menu:");
System.out.println(" P (Process Purchase)");
System.out.println(" S (Shut down)");
menu = scanner.next();
if (menu.charAt(0)=='S' || menu.charAt(0)=='s'){
System.exit(0);
}
else if (menu.charAt(0)=='P' || menu.charAt(0)=='p'){
System.out.println("Your choice: " + menu.charAt(0));
System.out.println("How many yougurts would you like to buy?");
numPurchases = scanner.nextInt();
totalPurchased += numPurchases;
}
if (totalPurchased > 0 && totalPurchased < 10){
System.out.println("you have purchased " + totalPurchased + " yogurts");
}
else if (totalPurchased >= 10){
System.out.println("Congradulations you have recieve a free Yogurt");
System.out.println("Remainding yogurt credits: " + (totalPurchased-10));
}
}
scanner.close();
}
}
Like mentioned above, you probably need some way to break out of the while loop by setting correct to true.
As user2357112 has stated in the comments, the || operator is inappropriate for testing if a number is in a given range since that condition would be true for any number.
You could change the condition to use && instead but I don't know why you'd only display that message on a certain condition. You could print it at the end of each purchase and then print an extra message if the user has received a freebie.
System.out.println("you have purchased " + totalPurchased + " yogurts");
if (totalPurchased >= 10){
System.out.println("Congradulations you have recieve a free Yogurt");
System.out.println("Remainding yogurt credits: " + (totalPurchased-10));
}
You also need to know that Scanner#nextInt() does NOT consume the trailing new-line character from user input. Scanner#nextLine() however, trims this character from the read input. As a result you'll get a StringIndexOutOfBoundsException after making a purchase since the Scanner#nextLine() to read in the user's choice at the menu will eat up the trailing new-line character and your program will try to get the first character of an empty String.
As stated in the linked thread you can fix this by calling Scanner#nextLine() again after reading integer input to remove the new-line character from the buffer like so:
numPurchases = scanner.nextInt();
scanner.nextLine();