I'm trying a simple do while loop that is suppose to run if the input is less than 1, and greater than 1000. It should ask for the user to input a correct number, on loop otherwise. What it seems to be doing now is repeating the loop one additional time, asking for the correct input, and then display the ending message. Unsure why it's repeating it, if the condition is met
String name = JOptionPane.showInputDialog(null,
"Please enter students lastname");
int input = Integer.parseInt(JOptionPane.showInputDialog(null,
"Please enter students ID"));
do {
JOptionPane.showMessageDialog(null,
"Please enter a student ID within the correct parameters");
input = Integer.parseInt(JOptionPane.showInputDialog(null,
"Please enter students ID"));
} while (input < 1 && input > 1000);
// Output dialog with user input
JOptionPane.showMessageDialog(null, "StudentID: " + input
+ "\nStudent Last: " + name);
You're presenting the dialog at least twice -- once before the loop, once within the loop.
The do-while does not test the condition until after the loop has executed at least once.
You could either:
Eliminate the first call to show the input dialog.
Or change your do-while loop to a while loop.
In addition, see #GrailsGuy's comments on the loop test. Your current test will always fail.
I think you while CONDITION is not correct as I read comments in print statement I believe you need
while (input > 1 && input < 1000);
Because ID must not negative number.
Remember this condition is true if ID value is between 2 to 999.
As you commented: Just to clarify, if the user inputs a number outside of the range (1-1000),i.e. 2005, I want the loop to cycle, asking the user to input a number within the range,until that condition is met
do like, read comments to understand what My code is:
input = -1;
while(input < 1 || input > 1000){
// ^ ^ OR greater then 1000
// either small then 1
}
notice: I have punted OR instead of AND because either one condition fail you loop should be continue.
I would change it with a while:
int input = Integer.parseInt(JOptionPane.showInputDialog(null,
"Please enter students ID"));
while(input < 1 || input > 1000) {
// Your stuff
}
The explanation
What I think was wrong is that, in the first place, there's no way any number can be (at the same time) less than 1 and more than 1000, so obviously, the valid input should be outside the specified range (that is, from -Infinity to 0 OR from 1001 to Infinity).
Secondly, what was mentioned in another answer: The do...while loop always runs at least once, and it repeats as long as the while condition is true. Since the input is being read before entering the loop, the 'confirmationalways takes place... What's the need to request a correction on a possibly correctinput` value?
What I think was wrong is a misunderstanding on the sense of the validation rule:
I'm trying a simple do while loop that is suppose to run if the input is less than 1, and greater than 1000
What does the and word means? I think it means that the input must be outside the given range.
Related
I was asked to create a mastermind game for school. The project never ran properly and I believe I went about the process in the wrong way. While the assignment is already past due I would like to know where I went wrong. Keep in mind we have still not gone over arrays.
This was the assignment description:
Your program will choose a random 4 digit number as the secret number. Your program must prompt the user to enter a 4 digit number as their guess. The program will respond with a message indicating how many of the digits in the user’s guess are the same as the digit in the same position in the secret number. For example, if the secret number is 3749, and the user’s guess is 9753, then the program would respond with the message You matched 1, because only one of the digits (the 7) in the user’s guess is the same as the digits in the same position in the secret number. The program will allow the user to continue to enter guesses until they guess the correct secret number. After the user has entered the secret number, the program will output a count of the total number of guesses the user took to find the secret number. Then the program will ask the user if they would like to play again. If the user answers “yes”, then the program will choose another random 4 digit number and play continues as described above.
Where was the best place to start for this assignment?
What was the best way to use loops?
How do I select different parts of the secret number?
Any help I can get now will help me catch up in the class.
import java.util.Scanner;
public class Assignment04 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("----- MASTERMIND -----");
System.out.println("Guess the 4 digit number!");
int secretNumber = (int)(Math.random() * 1000 + 1);
int usersGuess = 0;
int counter = 0;
int guessCount = 1;
for(int i=0; i<guessCount; guessCount++) {
System.out.print("Enter your guess: ");
usersGuess = in.nextInt();
if (String.valueOf(usersGuess).substring(0,0)==String.valueOf(secretNumber).substring(0,0));
{
guessCount ++;
counter ++;
break;
if (String.valueOf(usersGuess).substring(1,1)==String.valueOf(secretNumber).substring(1,1));
{
guessCount ++;
counter ++;
break;
}
if (String.valueOf(usersGuess).substring(2,2)==String.valueOf(secretNumber).substring(2,2));
{
guessCount ++;
counter ++;
break;
}
if (String.valueOf(usersGuess).substring(3,3)==String.valueOf(secretNumber).substring(3,3));
{
guessCount ++;
counter++;
break;
}
System.out.println("You matched " + guessCount);
if(counter==4);
{
System.out.println("Congratulations! You guessed the right number in " + counter + "guesses");
System.out.println("Would you like to play again? (Yes/No)");
}
}
}
}
}
This is all I was able to come up with.
So few points
Your for loop condition (i < guessCount) shouldn't be driven by the guess count because it should continue looping until they guess correctly.
You'd maybe want e.g. a boolean named "continueLooping" which is true and a while condition evaluating that instead of a for loop.
If the guessCount (which is summing the number of times the correct digits were aligned) is 4 then "continueLooping" would be set to false if the user said "No" when asked "Would you like to play again?"
You shouldn't be breaking after each matched digit. What if the first digit matches and the second digit matches? The break after the first match will stop the second digit ever being counted and the loop will exit
You want to check the length of their input to make sure it's 4 digits long
You'd want to use .equals() method of String rather than == as String is a reference type meaning equality is checked using equals() not the "==" operator (that is for checking primitive equality or exact reference equality)
Your "counter" should only increment once at the beginning of every loop
You GuessNumberRandomizer is wrong: it will produce 3 digit numbers only. Use this for 4 digits:
int secretNumber = (int)(Math.random() * 10000 + 1);
Also, I would suggest using String input or better yet, parse the integer input to String and use charAt() method for comparison instead. Also your usage of break may create some errors if more than 1 one digit was guessed correctly.
The first loop is is not really a good case scenario for a for loop. You should use a while loop. While will continue iterating, possibly infinitely, until the condition on which it's evaluated is no longer true.
Since your program should continue until the user guesses, or until he guesses right and doesn't want to play anymore, you should have a boolean "flag" which tells the game it should continue the loop. If the game has been won (when the correct guesses in a turn is equal to 4) then you should prompt the user if they want to continue playing, and if they say no, you just turn off the flag and the program exits.
Something like this
boolean continue = true;
int correctGuesses;
int numberOfTimesAttempted = 0;
while(continue){
numberOfTimesAttempted++;
correctGuesses = 0;
//Your game logic
if(correctGuesses == 4){
System.out.println("Do you wish to continue? Y or N");
char answer = sc.nextLine();
if(char.toUpper('N'){
continue = false;
System.out.println("It took you " + numberOfTimesAttempted + "to win!");
}
}
}
As some users pointed out, you should also have logic to verify that the user enters strictly 4 numbers.
Rather than comparing each number individually, simply convert the number to a char array and create a for loop that iterates through it. if the char at the current index is equal to the one in the secret number, increase the number of guess counts.
At the end of each loop, print the number of correct guesses. If number of guesses is 4, the user wins.
I am brand new at Java and this one is throwing me. Using the below code it loops through for the first question until I enter anything but an integer but after finishing that loop it does not stop for the remaining question.
Through a bit of research and reading I have found that I need to use the in.nextLine() to eat the newline character after the input. However no matter where I place the nextLine() it doesn't work? I thought it would be after the first int input = in.nextInt(); line but that did not work. Any help on where it would go and why?
System.out.print("How many CUs per course are remaining in your degree program? Enter any letter to quit: ");
while (in.hasNextInt()) { // Verify input is an integer
int input = in.nextInt();
if (input <= 0) // Verify that input is not negative or zero
{
System.out.println("Please enter a positive number or any letter to quit");
System.out.print("Add another course or any letter to quit: ");
} else {
courseCuList.add(input);
System.out.print("Add another course or any letter to quit: ");
}
}
System.out.print("How many CUs do you plan to take per term?");
while (in.hasNextInt()) {
int input = in.nextInt();
// in.nextLine(); This line consumes the \n
if (input <= 0) {
System.out.println("Please enter a whole positive number.");
System.out.println("How many CUs do you plan to take per term?");
} else {
cuPerTerm = in.nextInt();
}
}
Your problem is that in while (in.hasNextInt()) each call of hasNextInt needs to wait for user input, and then test if it is integer or not.
So each time user give integer, condition will be evaluated to ture, loop will execute and condition will need to be checked again, and if it is integer loop will execute again. This will go again and again until hasNextInt will be able to return false, for instance when user will give non-integer - like letter. But in this case condition in next loop will also return false because this non-integer value was not consumed after first loop. To let second loop work you would need to invoke nextLine two times
to consume line separator after previously put correct integer
to consume actual non-integer value
But this may also fail if user will not put any integer before non-integer value because there will be no line separator to consume.
So consider changing your logic to something similar to
boolean iterateAgain = true;
System.out.print("give me positive number: ");
while (iterateAgain) {
// this inner loop will move on only after getting integer
while (!in.hasNextInt()) {//here program waits for user input
in.nextLine();// consume non-integer values
System.out.print("that wasn't positive number, try again: ");
}
int number = in.nextInt();// now there must be number here
in.nextLine();// consume line separator
if (number > 0) {
System.out.println("you gave " + number);
// do what you want with this number
iterateAgain = false;// we can leave loop
} else
System.out.print("that wasn't positive number, try again: ");
}
If you want to execute next loop then all you need is reset iterateAgain value to true.
You need to read twice.
The exit condition on your while loop is hasNextInt() - checking to see if the next token is an integer doesn't actually clear that token, which means that the next nextLine() is going to read the token, and the subsequent nextLine() will read the newline character.
To demonstrate this, place the following between the loops:
System.out.println(in.nextLine() + " | " + in.nextLine());
For the input 4, 4, A, you will see the output:
How many CUs per course are remaining in your degree program? Enter any letter to quit: 4
Add another course or any letter to quit: 4
Add another course or any letter to quit: A
| A
How many CUs do you plan to take per term?
There are two tokens that need to be cleared from the buffer, and neither of them are integers. Because of this, no matter where you put nextLine(), it will fail - you need to insert it twice. If you only insert it once, the next token won't be an integer, and hasNextInt() will fail when the program tries to enter the second loop.
In order to get your program to work, simply insert:
in.nextLine(); in.nextLine();
before the second loop. (Note that you shouldn't put both this and the print-out in, as this will read four times.)
I'm a bit confused as to why I need the do-while loop in this piece. What I am trying to do is count the number of times a user inputs a character. The count should stop when the user types a ".". When I try to run the program without the do-while, the count of x is multiplied by 3. I've read online that the console input is line buffered. The way I understand it, is a an entire line is created by one character and as such there are actually more characters? Is my understanding correct? And if possible, could I have an explanation of the do-while loop?
public class readCharLengths {
public static void main(String args[])
throws java.io.IOException {
char typed, ignore;
int x=0;
for ( ; ; ) { //infinite loop to keep reading in values
typed = (char) System.in.read(); //get typed character
do { //confused here
ignore = (char) System.in.read(); //confused here
} while (ignore != '\n'); //confused here
if (typed =='.') break; //break loop when . is typed
x++; //increment x
}
System.out.println("The number of characters is: " + x); //print x
}
}
It depends on the circumstances around how a user is giving input into the console. If they insert one character at a time, each on a separate line. Or if they input a string of characters, basically like a sentence, and then you count the number of characters until a period is reached.
If it is one character per line, I would suggest:
int x = 0;
Scanner in = new Scanner(System.in);
while (true) {
String input = in.nextChar();
if (input.equals('.') {
break;
} else {
x++;
}
}
If it is a string of characters, I would suggest:
int x = 0;
Scanner in = new Scanner(System.in);
String input = in.nextLine();
for (int i=0; i<input.length(); i++) {
if (input.charAt(i).equals('.') {
break;
} else {
x++;
}
}
To answer what a do...while loop is, I'm going to go into some very basic programming concepts. I don't mean to be condescending if I come across that way: I just don't know your skill level with programming, so I'm assuming you are very new to it.
First, let me explain the concept of a loop condition. A loop condition is code that, when it is evaluated while your program runs, will either come out to true or false. So, in the case of a regular while loop, the format is:
while (loop condition) {
run some code, maybe multiple times
}
When your code reaches the while line of code it evaluates the condition and decides whether to run the code inside the loop's braces.
Let's say your condition is "x must be less than 5". You might have a while loop like this:
int x = 0;
while(x < 5) {
System.out.println("A");
x++;
}
This code will print A on 5 lines because x = 0 when it reaches the while statement the first time, and since 0 < 5 evaluates to true, the loop's code is going to execute. When the end of the loop is reached, it jumps up to the loop condition and evaluates it again. This time, x = 1 because we added 1 to x. Since 1 < 5, the loop happens again. This happens a total of 5 times and then when it evaluates the loop condition, you have it try 5 < 5, which is false. It skips the loop code and continues the program at this point.
A do...while loop is based on the same idea. Instead of checking the loop condition at the start of the loop, it is checked at the end. So...
int x = 0;
do {
System.out.println("A");
} while(x < 0);
This code will output A once. Even though the loop condition is not met (since x starts at 0), when you use a do...while, the loop code is always executed at least once. At the end of the loop, the condition is checked and since 0 < 0 is false, the loop does not repeat.
So, on to how System.in.read() works. You have it right that it buffers the input until a linebreak is reached. But do you actually know what that means?
Here's how it works. You start typing stuff into the console. Say you type aabbcc and then press enter. Your program waits when it calls System.in.read() until user input is sent back to the program. It does not continue running when the first a is typed though! Your program only gets to continue running once you press enter (that is, a linebreak is sent).
The idea of buffering input is that all the letters you typed are stored and available once your program starts running again. So when your program runs after you have entered aabbcc, all of those letters are available (and also the linebreak for the enter key you pressed).
With your code, that means that the first time you call System.in.read(), you get back the character a, but there is still abbcc and newline waiting. It enters the loop and reads each character. So it reads a, then b, then b, then c, then c, then newline. At this point the loop condition is false and the loop ends.
Well, there are a couple of things about this.
First, this might not do what you want because the do/while loop will consume every character after the first one without incrementing the counter until it hits the LF. So, your count will always be 1 with the do/while loop in place assuming you type at least one character and then hit Enter. However, if your intention is that the user is allowed to enter only one character at a time (followed by Enter), then see the second item.
Second, console input defaults to buffered until you press Enter. So, if you take the do/while loop out, enter a single character and press Enter, you'll actually get three characters on Windows--the character you typed, CR and LF. Assuming you're testing with single characters, that would explain the multiplication by 3.
In the following code, the statement after ''Digit 2 is marked as unreachable. Why?
while(true){
System.out.println("Welcome to Pi Conquest!");
System.out.println("Name as many digits of Pi as you can");
System.out.println("If you get an error you restart");
System.out.println("Only includes up to 100 digits of Pi");
System.out.println("---------------------------------------");
System.out.println("");
Scanner keyboard = new Scanner(System.in);
//Digit 1
System.out.println("Stats:");
System.out.println("Number of Digits Entered: 0");
System.out.println("Digits Entered: 3.");
System.out.println("Enter the first digit of Pi. (Starting with decimals)");
int digit1 = keyboard.nextInt();
if(digit1==1){
System.out.println("Correct, enter the next digit.");
continue;
}else{
System.out.println("Incorrect, restarting.");
break;
}
//Digit 2 <--------------------------------------- next statement marked unreachable
System.out.println("Stats:");
System.out.println("Number of Digits Entered: 1");
System.out.println("Digits Entered: 3.1");
int digit2 = keyboard.nextInt();
if(digit2==4){
System.out.println("Correct, enter the next digit.");
continue;
}else{
System.out.println("Incorrect, restarting.");
break;
}
}
Because in the previous if, either the branch that ends with continue or the branch that ends with break will be executed.
Both these instructions will cause the current iteration to end, so there is no way in which more code may be executed.
The first option in this statement leads to restarting the loop, and the second one - ends the loop and starts execution of code after the while loop. So, the next lines won't be reached.
if(digit1==1){
System.out.println("Correct, enter the next digit.");
continue;
}else{
System.out.println("Incorrect, restarting.");
break;
}
Your first if statement either fails or continues the loop (it does not continue the "code"), so nothing after the first if statement will ever be executed.
You might want to consider coding your request differently (e.g. step through the digits of pi in a String answer, providing feedback to the user.
All code below //Digit 2 comment is unreachable. I think that you didn't get what continue statement means. When you run while loop it gets int from keyboard by
int digit1 = keyboard.nextInt();
and according to your code
if(digit1==1){
System.out.println("Correct, enter the next digit.");
continue;
}else{
System.out.println("Incorrect, restarting.");
break;
}
If it is 1 it will start loop from begining. Otherwise loop will break. I think that you expected continue to run your code after if else statement but continue runs loop again from the very begining.
If you want to run next line of code after if else just remove continue.
You are using continue and break wrong. Your breaks should be continues and your continues should be simply removed.
if(digit1==1){
System.out.println("Correct, enter the next digit.");
}else{
System.out.println("Incorrect, restarting.");
continue;
}
break exits the while(true) loop and since there's nothing else after that loop, your program ends. Instead, you want to start a new loop iteration at this point (and skip over the remaining of the current iteration), thus you need a continue.
As mentioned earlier, continue starts a new loop iteration. Instead, you want to simply go on with the current iteration. You don't need anything fancy for this: just let the if block do its thing and continue after the if...else statement.
Off-topic: you'll have quite a lot of code duplication if you continue in this fashion for the other digits. I suggest you look into making a for loop over the digits of pi so you can compare the "current digit" with the entered number.
This question already has answers here:
try/catch with InputMismatchException creates infinite loop [duplicate]
(7 answers)
Closed 7 years ago.
I am making a method in order to get how many numbers the user wants to sum together. aka if they want to sum the numbers 1 2 and 3. they would want to sum 3 numbers together. So when i ask them how many they want to sum together, I use a try - catch in order to catch if they enter a decimal place. Because you cant add together 3.5 numbers you can add 3 numbers or 4. problem is if the user enters a decimal, the program will infinite loop run everything but what is in the try statement. How can i fix this?
Here is the code for the method:
private static int requestMaxInputForFloat(Scanner scanner){
boolean appropriateAnswer = true; // assume appropriate catch not appropriate to loop again
int howManyInputs = 1000000; // hold value to return how many inputs. if this value we will not run.
//request an appropriate number of inputs until appropriate answer = true;
do
{
appropriateAnswer = true; //if looped again reset value to true
try{
System.out.print("How many decimal place numbers would you like to sum? ");
howManyInputs = scanner.nextInt();
}catch(Exception e){
System.out.println("Sorry but you can only request to average a whole number set of data.\nTry Again.");
appropriateAnswer = false;
}//end of try-catch
if (howManyInputs <= 0) //invalid answer
{
System.out.println("Sorry but " + howManyInputs + " is equal to or below 0. Please try again.");
}else{
appropriateAnswer = false;
}
}while(!appropriateAnswer);//end of while loop
return howManyInputs; //return the value
}// end of getMaxInput
Add scanner.nextLine(); in the catch block. I think the problem is that if nextInt() gets an error, the scanner's "pointer" is still pointing at a bad character, and if you just try nextInt() again, it will try to scan the same bad character over again. You have to do something to make the scanner skip over it. Here, you want to just throw away whatever the user typed in, so nextLine(), which skips over the entire remainder of the input line, is the most appropriate.
One other thing: I'd change
if (howManyInputs <= 0) //invalid answer
to
if (appropriateAnswer && howManyInputs <= 0) //invalid answer
Otherwise, if the user types in -1, then the loop will go back and howManyInputs will still be -1; then if the user types 3.5, you'll get the exception but you'll get a second error message because howManyInputs is still -1 left over from the previous loop. You don't need to test howManyInputs if you already know there was an input error.