Java Loop: Why does this loop not stop as expected? - java

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();

Related

while loop incrementing an extra time

The below while loop runs an extra time. I am trying to perform a user input that accepts 10 valid numbers from the user and prints their sum. However, the while loop executes an extra time and asks for the 11th input.
import java.util.Scanner;
class userInput{
public static void main(String[] args) {
int i = 1, sum = 0;
Scanner sc = new Scanner(System.in);
while(i <= 10){
i++;
System.out.println("Enter number " + "#" +i);
boolean isValidNumber = sc.hasNextInt();
if(isValidNumber){
int userChoiceNumber = sc.nextInt();
sum += userChoiceNumber;
}else{
System.out.println("Invalid Input");
}
}
System.out.println("The sum of your entered numbers are = " + sum);
}
}
In addition to those great comments, you should probably only increment "i" if you get a VALID input:
while(i <= 10) {
System.out.print("Enter number " + "#" +i + ": ");
boolean isValidNumber = sc.hasNextInt();
if(isValidNumber){
int userChoiceNumber = sc.nextInt();
sum += userChoiceNumber;
i++;
}else{
System.out.println("Invalid Input");
sc.next();
}
}
Note that when you have a bad input you need to get rid of it with "sc.next()".
First - make sure you're formatted correctly.
(I've indented your loops, moved your output into the main class, fixed up some curly brackets/loop endings).
public static void main(String[] args) {
int i = 1, sum = 0;
Scanner sc = new Scanner(System.in);
while(i <= 10){
i++;
System.out.println("Enter number " + "#" +i);
boolean isValidNumber = sc.hasNextInt();
if(isValidNumber){
int userChoiceNumber = sc.nextInt();
sum += userChoiceNumber;
}
else{
System.out.println("Invalid Input");
}
}
System.out.println("The sum of your entered numbers are = " + sum);
}
Alright - so running the code, I've found there are the correct amount of times asked, but the input prompt is displaying the wrong number with the first input prompt starting on 2, the last one on 11.
The reason for this is the i++ runs before asking for an input, thus it counts up before outputting.
This can easily be fixed by moving said i++ to just underneath the else clause - as follows:
else{
System.out.println("Invalid Input");
}
i++
}
the main problem here is that you're increasing the variable at the start of your while loop. If that's what you're looking for then that's fine, but if you want to stop the loop when it hits 10 you'll need to have it like while(i < 10) if the i++ were at the end of the loop, then you could do while(i <= 10)
Ex:
i = 0;
while(i < 10){
i++;
//code here
}
this will make the code that uses i use the values between 1 and 10. using <= will use the values between 1 and 11.
another example:
i = 0;
while(i < 10){
//code here
i++;
}
this will make the code that uses i use the values between 0 and 9. using <= will use the values between 0 and 10.
another way people do an incremental loop is doing a for loop rather than a while loop
this would look like:
for(int i = 0; i < 10; i++){
//code here
}
this also allows you to create a variable that will only be inside the loop, so rather than making it at the beginning of the method or before the loop, you could make it inside the for loop. This is not good if the variable is used elsewhere though.

infinite loop in a while statement

import java.util.Scanner;
public class Main {
public static void main(String[] args) {
System.out.println("\nThe sum of the numbers is: " + getSumOfInput());
}
public static int getSumOfInput () {
int counter = 0;
int sumOfNums = 0;
Scanner userInput = new Scanner(System.in);
while(counter <= 10) {
System.out.print("Enter the number " + counter + ": ");
boolean checkValidity = userInput.hasNextInt();
if(checkValidity) {
int userNum = userInput.nextInt();
userInput.nextLine();
System.out.println("Number " + userNum + " added to the total sum.");
sumOfNums += userNum;
counter++;
} else {
System.out.println("Invalid input. Please, enter a number.");
}
}
userInput.close();
return sumOfNums;
}
}
Hello everybody!
I just started java and I learned about control flow and now I moved on to user input, so I don't know much. The problem is this code. Works just fine if you enter valid input as I tested, nothing to get worried about. The problem is that I want to check for wrong input from user, for example when they enter a string like "asdew". I want to display the error from else statement and to move on back to asking the user for another input, but after such an input the program will enter in an infinite loop displaying "Enter the number X: Invalid input. Please, enter a number.".
Can you tell me what's wrong? Please, mind the fact that I have few notions when it comes to what java can offer, so your range of solutions it's a little bit limited.
Call userInput.nextLine(); just after while:
...
while(counter <= 10) {
System.out.print("Enter the number " + counter + ": ");
userInput.nextLine();
...
The issue is, that once you enter intput, which can not be interpreted as an int, userInput.hasNextInt() will return false (as expected). But this call will not clear the input, so for every loop iteration the condition doesn't change. So you get an infinite loop.
From Scanner#hasNextInt():
Returns true if the next token in this scanner's input can be interpreted as an int value in the default radix using the nextInt() method. The scanner does not advance past any input.
The fix is to clear the input if you came across invalid input. For example:
} else {
System.out.println("Invalid input. Please, enter a number.");
userInput.nextLine();
}
Another approach you could take, which requires less input reads from the scanner, is to always take the next line regardless and then handle the incorrect input while parsing.
public static int getSumOfInput() {
int counter = 0;
int sumOfNums = 0;
Scanner userInput = new Scanner(System.in);
while (counter <= 10) {
System.out.print("Enter the number " + counter + ": ");
String input = userInput.nextLine();
try {
int convertedInput = Integer.parseInt(input);
System.out.println("Number " + convertedInput + " added to the total sum.");
sumOfNums += convertedInput;
counter++;
} catch (NumberFormatException e) {
System.out.println("Invalid input. Please, enter a number.");
}
}
return sumOfNums;
}

I am creating a game of hangman. Having two issues with it right now

first off, the secret word is printed out as dashes, then the user puts in what letter they want to guess. if they guess the letter correctly then it will update the dashes. so if the word is java, it will show as ---- and if the user types a, then it will update and show -a-a . my program does that but it also adds extra dashes at the end and i don't know how to make it not print those extra dashes. and that brings me to another problem i am having, the user is asked at what indexes they want to guess the letter. so if the user types the letter a and at index 1, then the updated word will show -a--, but my program updates all instances of where the a is at, so it shows -a-a. here is my code:
import java.util.Scanner;
public class HangMan2 {
private static final boolean testingMode = true;
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
int guessRemaining = 20;
int rounds = 1;
int roundScore;
String wordString = "";
String word = RandomWord.newWord();
int length = word.length();
for(int i = 0; i < length; i++)
{
wordString += "-";
}
System.out.println("The word is: " +wordString);
System.out.println("The secret word is: " +word);
System.out.println("Enter the number of spaces allowed");
int spacesAllowed = keyboard.nextInt();
keyboard.nextLine();
if(spacesAllowed > length)
{
System.out.println("Invalid input. Try again.");
System.out.println("Enter the number of spaces allowed");
spacesAllowed = keyboard.nextInt();
}
while(guessRemaining > 0) {
System.out.println("Please enter the letter you want to guess: ");
String letterGuess = keyboard.next();
char letterCharacter = letterGuess.charAt(0);
System.out.println("Please enter the number of spaces you want to check (seperated by spaces): ");
String spacesChecked = keyboard.next();
boolean guessCheck;
// check if the letter is in the string
guessCheck = (word.indexOf(letterCharacter)) != -1;
if(guessCheck == true)
{
for (int i = 0; i < word.length(); i++) {
if (letterCharacter == word.charAt(i)) {
wordString = wordString.substring(0, i) + letterGuess + wordString.substring(i);
System.out.println("Your guess is in the word!");
System.out.println("The updated word is: " +wordString);
} //end of if statement
} //end of for loop
}
else
{
System.out.println("Your letter was not found in the spaces you provided");
guessRemaining--;
System.out.println("You have " +guessRemaining+ " guesses remaining.");
}
}
if(guessRemaining != 0)
{
System.out.println("You win!");
System.out.println("You have guessed the word! Congratulations");
roundScore = (guessRemaining * 10) / spacesAllowed;
} //end of if
else{
System.out.println("Guesses Remaining: 0");
System.out.println("You have failed to guess the word... :(");
}
System.out.println("Would you like to play again? Yes (y) or No (n)");
String playAgain = keyboard.next();
if(!playAgain.equals("y") && !playAgain.equals("n"))
{
System.out.println("Invalid response, please try again... ");
}
if(playAgain.equals("y"))
{
rounds++;
}
else
{
System.exit(0);
}
}
}
wordString = wordString.substring(0, i) + letterGuess + wordString.substring(i);
if ((wordString.substring(0,i) + wordString.substring(i)).equals(wordString))
System.out.println("These are completely identical");
else
System.out.println("You solved it yourself ;)");
hint: it's 58 in your posted code.
Second part: Completely different program structure.
You'll need to track user's two guessed values, one as a character, the other as an int.
You will compare wordString.toCharArray()[indexUserGuessed] to characterUserGuessed and update the result or game state as needed, using similar code from the way you solved the if statement paradox I provided.
Finally, Welcome to Stack Exchange. MOST of us won't do your homework for you.
Oh and I would look up examples of "StringBuilder Java" as you might find it easier to manipulate your String with this class than with String.

Correct user input not matching array values

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();
....
}

Java Looping issue in Hangman program(Cant find)

I have the majority of my program finished, but now that I have most of the code it is tough to find the errors. I have multiple errors at the moment, but the main error I really need help with is that my program will loop the same guess over & over if it is correct. It is in an infinite loop, & I cannot find where it is. This has also brought to my attention that my program will go into negative guesses as it is supposed to end when it gets to 0. Some other errors that would be nice to get help with is 1) it shows a correct guess as an incorrect guess 2) it can only replace one letter in the secret word if there are multiple it will give me an error & end the program. & 3) if I enter 9 to quit, it does not quit.
Thanks in advance for any help. I can add code if needed ( I am only posting the main body ATM.)
public static final int DICTIONARY = 15000;
public static final int GUESSES = 8;
public static final int SECRETLENGTH = 20;
public static void main(String[] args) {
int usedSize = 0, randomWord, guesses = GUESSES;
String word, secretWord, guess, incorrectGuess, correctWord, playAgain;
char letter;
try
{
// Set up connection to the input file
Scanner hangmanDictionary = new Scanner(new FileReader("dictionary.txt"));
String [] dictionary = new String [DICTIONARY];
while (usedSize < DICTIONARY && hangmanDictionary.hasNextLine()) {
dictionary[usedSize] = hangmanDictionary.nextLine();
usedSize++;
}
kbd.nextLine();
clearScreen();
randomWord = pickRandom(DICTIONARY);
word = dictionary[randomWord];
secretWord = secret(word);
//comment out when done testing
System.out.println(word);
System.out.println("Here is the word to guess: " + secretWord);
System.out.println("Enter a letter to guess, or 9 to quit.");
guess = kbd.next();
do {
while (!guess.equals("9") || !(guess.equals(word) && guesses > 0)) {
letter = guess.charAt(0);
incorrectGuess = "";
incorrectGuess += letter;
if (word.indexOf(letter) < 0) {
guesses--;
System.out.println("Incorrect guesses: " + incorrectGuess);
System.out.println("Number of guesses left: " + guesses);
System.out.println("Enter a letter to guess, or 9 to quit.");
guess = kbd.next();
}
else {
//FINSH THIS
correctWord = correctWord(guess, word, secretWord, letter);
System.out.println(correctWord);
System.out.println("Incorrect guesses: " + incorrectGuess);
System.out.println("Number of guesses left: " + guesses);
System.out.println("Enter a letter to guess, or 9 to quit.");
guesses--;
}
}
if (guess.equals("9")) {
System.out.println("Thanks for playing!");
System.exit(0);
}
if (guess.equals(word)) {
System.out.println("You won!");
}
if (guesses == 0) {
System.out.println("You are out of guesses.");
}
System.out.println("Play again? Y/N");
playAgain = kbd.nextLine().toUpperCase();
} while (playAgain.equals("Y"));
}
catch (FileNotFoundException e) {
System.out.println("There was an error opening one of the files.");
}
}
Here's my guess:
Did you forget to put guess = kbd.next(); if the user guessed a correct character?
The inner while loop is your main problem, i.e. think about what happens when you enter a valid letter (guess), in that case the first condition of the while loop OR condition is TRUE (assuming you don't have a 9 in your secret word), so the while loop is entered without entering the second part of the OR condition. After that you enter the else part of the IF statement (since it's a valid guess) but in the else part you're not asking for the next guess, so it returns to the start of the while loop with the same guess and hence infinite loop.
Similarly, if you enter 9 to exit !guess.equals("9") evaluates to FALSE, so the second part of the OR condition is entered, in the second part
!(guess.equals(word) && guesses > 0) evaluates to TRUE (unless the secret word contains a 9) so you enter the WHILE loop which is invalid. etc ...
Try to write small parts of the code using known parameters and then bring it all together, that way it'll be easier to construct and follow the logic.

Categories

Resources