How to fix this infinite loop? (AP Computer Science) - java

public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
System.out.print("Please enter a digit: ");
int digit = in.nextInt();
boolean isAnInteger = false;
while (isAnInteger)
{
if (digit >= 10)
{
System.out.println("Please enter an integer: ");
}
else
{
System.out.println("Correct! " + digit + " is an integer!");
}
}
}
I'm currently taking AP Computer Science and I'm curious as to how to solve this (albeit basic) issue. I'm aware that "while" loops continue whatever is in their respective curly brackets when a condition in their parenthesis continues to be a met.
When I tried setting the while condition to while (digit >= 10), it resulted in an infinite loop (correct me, but it is due to the fact that if the user inputs a digit of 10 or greater, the condition will KEEP being met and continue infinitely). So, I tried setting the while condition to some boolean value, and an if nested inside with the prior condition. Now, when the user enters 10, nothing happens after, and the program ends.
How do I write the above code so that the System will continue printing "Please enter an integer:" if the condition (of inputting 10 or greater and the opposite) continues to be met?

There is a basic "poor design" issue that the variable isAnInteger has a scope wider than needed (it lives past the last line that needs it).
The "correct" approach is loop that contains the logic that determines "integerness" of the input and doesn't leave variables in scope when the loop ends, other than the captured input in digit of course.
Next, you want to separate the concerns of capturing input with checking it, so first create a method that gets a digit:
private static int readNumber(Scanner in) {
System.out.print("Please enter a digit: ");
int digit = in.nextInt();
in.nextLine(); // you must clear the newline char from the buffer
return digit;
}
Next, write a simple while() loop that keeps reading until it gets good input:
int digit = 10; // bad input
while (digit > 9) {
digit = readNumber(in);
}
Putting it all together with the final message:
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int digit = 10; // initialize with "bad" input
while (digit > 9) {
digit = readNumber(in);
}
System.out.println("Correct! " + digit + " is an integer!");
}
private static int readNumber(Scanner in) {
System.out.print("Please enter a digit: ");
int digit = in.nextInt();
in.nextLine(); // you must clear the newline char from the buffer
return digit;
}
This approach makes the code much easier to read and understand.
Also notice how there is no repeated code (such as the line asking for a digit, or reading input).

The main conceptual piece here is that you don't update your value anywhere inside of your loop. Because it does not update, it will always remain the value it was when it entered the loop (that is, digit >= 10 will remain true until the program stops running).
You must update your values inside of your loop.
However, there's another concept you're missing: you're guaranteed to run the loop at least once, so you should take advantage of the do...while loop instead.
Note that I make use of nextLine() to avoid any wonky nextInt() issues.
(Oh, by the way: any number you're looking for is an integer. You should communicate that you're looking for an integer less than 10 instead.)
System.out.print("Please enter a digit: ");
int digit = Integer.parseInt(in.nextLine());
boolean isAnInteger;
do {
if (digit >= 10) {
System.out.println("Please enter an integer: ");
digit = Integer.parseInt(in.nextLine());
isAnInteger = false;
} else {
System.out.println("Correct! " + digit + " is an integer!");
isAnInteger = true;
}
} while (isAnInteger);

Yes, Makoto has it right.
You never update your values inside the while loop. In your original case, when you just wanted to keep printing out Please enter an integer: , you never ask for an input right after that line. Your original digit value will continue to be greater than or equal to 10, and will keep the loop going.
Even with your current code, you will still run into an infinite loop if your digit value is less than 10. Notice how the boolean isAnInteger is independent of whether your digit is less than 10.
The best way to fix this is by using something like this:
in = new Scanner(System.in);
System.out.print("Please enter a digit: ");
int digit = in.nextInt();
while (digit >= 10)
{
System.out.println("Please enter an integer: ");
digit = in.nextInt();
}
System.out.println("Correct! " + digit + " is an integer!");
What this does is it keeps checking to see if digit is greater than or equal to 10. If so, it will continue to ask the user for an input. If at any time during the iteration of the loop the user enters a value less than 10, it will not execute the next iteration, and leaves the loop. It will then execute the last println.
However, if the first input is less than 10, it will skip the while loop and execute the println at the bottom.
If you want to use a boolean like you did, you can do it in such a manner:
in = new Scanner(System.in);
System.out.print("Please enter a digit: ");
int digit = in.nextInt();
bool isAnInteger = true;
if (digit >= 10)
isAnInteger = false;
while (!isAnInteger) // checks if digit is not an integer
{
System.out.println("Please enter an integer: ");
digit = in.nextInt();
if !(digit >= 10)
isAnInteger = true;
}
System.out.println("Correct! " + digit + " is an integer!");
Makoto's way of using a do while loop is probably better, although this may be a better way of visualizing it (since you used a while loop).

Related

how to end a while loop with a certain variable

I am making an odd or even program with a while loop. I am trying to figure out how to end the while loop with a certain number. Right now I have 1 to continue the loop, and trying to make 2 the number that terminates it. Also trying to figure out how to terminate the program if a user types anything but a number like a letter/words.
package oddoreven;
import java.util.Scanner;
public class oddoreven {
public static void main (String[] args){
int num;
int x = 1;
while(x == 1) {
System.out.println("Enter a number to check whether or not it is odd or even");
Scanner s = new Scanner(System.in);
num = s.nextInt();
if (num % 2 == 0)
System.out.println("The number is even");
else
System.out.println("The number is odd");
//trying to figure out how to get the code to terminate if you put in a value that isn't a number
System.out.println("Type 1 to continue, 0 to terminate");
x = s.nextInt();
}
}
}
You should try to use "a real termination condition" in order to terminate a while loop (or any loop for that matter); it's cleaner and should be easier to understand by everyone else.
In your case, I think it's better to have a do-while loop with some condition around this logic: num % 2 == 0, and an inner while loop for handling user input/validation.
If you still want to break loops abruptly, have a look here.
If you still need some help with the code, hit me up and I'll sketch up something.
I did not follow the conditions you wanted exactly because it does not make sense to have a continue condition AND a terminate condition unless there are other options.
What did you want the user to do if he entered 3, 4 or 5? Exit the code or continue the code? Well if the default is to exit, then you do not need the code to exit on 2 because it already will! If the default is to continue, then you do not need the continue on 1 and only the exit on 2. Thus it is pointless to do both in this case.
Here is the modified code to use a do while loop to ensure the loop is entered at least 1 time:
int x;
do {
System.out.println("Enter a number to check whether or not it is odd or even");
Scanner s = new Scanner(System.in);
int num = s.nextInt();
if (num % 2 == 0)
System.out.println("The number is even");
else
System.out.println("The number is odd");
//trying to figure out how to get the code to terminate if you put in a value that isn't a number
System.out.println("Type 1 to check another number, anything else to terminate.");
if (!s.hasNextInt()) {
break;
}
else {
x = s.nextInt();
}
} while(x == 1);
}
Note that I added a check to !s.hasNextInt() will check if the user enters anything other than an int, and will terminate without throwing an Exception in those cases by breaking from the loop (which is the same as terminating the program in this case).
If the x is a valid integer, then x is set to the value and then the loop condition checks if x is 1. If x is not 1 the loop terminates, if it is it will continue through the loop another time.
Another thing you can try is that instead of exiting the program you can just keep asking user to enter correct input and only proceed if they do so. I don't know what is your requirement but if you want to go by good code practice then you shouldn't terminate your program just because user entered wrong input. Imagine if you googled a word with typo and google just shuts off.
Anyways here is how I did it
import java.util.Scanner;
public class oddoreven {
public static void main(String[] args) {
int num;
int x = 1;
while (x == 1) {
System.out.println("Enter a number to check whether or not it is odd or even");
Scanner s = new Scanner(System.in);
boolean isInt = s.hasNextInt(); // Check if input is int
while (isInt == false) { // If it is not int
s.nextLine(); // Discarding the line with wrong input
System.out.print("Please Enter correct input: "); // Asking user again
isInt = s.hasNextInt(); // If this is true it exits the loop otherwise it loops again
}
num = s.nextInt(); // If it is int. It reads the input
if (num % 2 == 0)
System.out.println("The number is even");
else
System.out.println("The number is odd");
// trying to figure out how to get the code to terminate if you put in a value
// that isn't a number
System.out.println("Type 1 to continue, 0 to terminate");
x = s.nextInt();
}
}
}
To exit the program when the user enters anything other than a Number, change the variable x type to a String
if (!StringUtils.isNumeric(x)) {
System.exit(0);
}
To exit the program when user enters 2
if (x == 2) {
System.exit(0);
}

Java number guessing

a. declare a final int, and assign a value of 6 as the guessed number
// b. create a Scanner to get user input
// c. use a do {} while loop to prompt the user to enter an integer between 1 and 10,
// assign the user input to an int, and compare to the guessing number
do{
} while ();
// d. if the number matches the guessed number,
// print out a message that the number entered is correct.
I am stuck on the do while loop portion of the problem
import java.util.Scanner;
public class Number {
public static void main(String[] args) {
int value = 6;
int guess = 0;
int num = 0;
do {
System.out.println("Please enter a number between 1 and 10: ");
Scanner number = new Scanner(System.in);
guess = number.nextInt();
} while (num <= 10);
if (guess == value);
System.out.println("Congratulations you guessed the correct number!");
if (guess != value);
System.out.println("The number does not match.");
}
}
This is the result I am getting. I cannot figure out why it wont print the messages saying the number is correct or the number did not match.
Please enter a number between 1 and 10:
4
Please enter a number between 1 and 10:
5
Please enter a number between 1 and 10:
6
The semicolon after the if statement stops it from working and makes no sense
if (guess == value);
^ No no no
Should be
if (guess == value) {
System.out.println("Congratulations you guessed the correct number!");
}
Or
if (guess == value)
System.out.println("Congratulations you guessed the correct number!");
You should also increment num or the while makes no sense
Remove the Semicolon after the ifstatement, and i strongly advise you to use {} to wrap all your statements.
Morover you should increase num inside your while loop, and move the guessing part inside your while loop. so the correct messages are printed out in every loop.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int value = 6;
int guess = 0;
int num = 0;
do {
System.out.println("Please enter a number between 1 and 10: ");
Scanner number = new Scanner(System.in);
guess = number.nextInt();
num++;
if (guess == value) {
System.out.println("Congratulations you guessed the correct number!");
break;
}
if (guess != value) {
System.out.println("The number does not match.");
}
} while (num <= 10);
}
}
You code basically looks like this:
ask user for a number from 1 to 10
and do this forever
now check whether the number entered is the right guess
So as long as the user does what he is told, you keep asking and reasking. You never get to "now check...".
The loop needs to encompass the checking for the right guess, and needs to be terminated on the right guess.
(Edited) I slightly misread the original code, thinking that 'num' was the input value. Nope, the input number is called 'number'. I suggest the counter be renamed for clarity, maybe 'guessCount'. And of course remember to increment it with each guess.

How can I check for invalid input and loop until the input is valid?

I am trying to find the smallest number in the list from user input. I need to ask the user how many numbers are going to be in the list (and only accept positive numbers and no letters) and then ask them what the numbers are in the list (accepting only numbers). How can I check for this and keep looping until the numbers are valid?
public class SmallestInt {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// Initialize a Scanner to read input from the command line
Scanner input = new Scanner(System. in );
int totalIntegers = 1;
int num = 0;
int smallest = 0;
boolean inputValid = false;
/* Prompt the user and validate their input to ensure they've entered a positive (greater than zero) integer. Discard/ignore any other data.
*/
while (!inputValid)
{
System.out.print("How many integers shall we compare? (Enter a positive integer): ");
try {
totalIntegers = input.nextInt();
inputValid = true;
} catch (NumberFormatException e) {
System.out.println("Invalid input!");
}
/* Read in the candidates for smallest integer
* Validate this input as well, this time ensuring that the user has provided a valid int (any int will do at this point) and discarding any other data
*/
for (int ii = 1; ii <= totalIntegers; ii++) {
// Prompt
System.out.print("Enter value " + ii + ": ");
num = input.nextInt();
if (ii == 1) smallest = num;
else if (num < smallest) smallest = num;
}
// display smallest int
System.out.println("The smallest number entered was: " + smallest);
}
}
}
Let's come up with an sample for you so you can follow as your blueprint
first, I chose do while loop because you need to ask this question at least once.
he syntax of a do...while loop is:
do
{
//Statements
}while(Boolean_expression);
Notice that the Boolean expression appears at the end of the loop, so
the statements in the loop execute once before the Boolean is tested.
If the Boolean expression is true, the flow of control jumps back up
to do, and the statements in the loop execute again. This process
repeats until the Boolean expression is false.
Next, you need to see how you can staisfy the boolean_experssion when the input is right, so you can stop looping or if it is wrong, you keep asking the question.
The way that I really like is to use sentinel value because using break keyword really scares me.
In programming, a special value that is used to terminate a loop. The
sentinel value typically is chosen so as to not be a legitimate data
value that the loop will encounter and attempt to perform with. For
example, in a loop algorithm that computes non-negative integers, the
value "-1" can be set as the sentinel value as the computation will
never encounter that value as a legitimate processing output.
so when the input is right you change the value of i, so you can stop the looping or otherwise, showing the message and asking the question again and again till the use hits the right answer.
Code:
int i = 0;
Scanner input = new Scanner(System.in);
while (i == 0) {
System.out.println("Enter number zero plz");
int result = input.nextInt();
if(result == 0 ){
System.out.println("I entered right number");
i = 1;
} else
System.out.println("you entered the wrong number \nplz try again");
}
output:
Since this is clearly a homework / learning exercise, I won't give you code. You will learn more if you do the actual coding for yourself.
Once you have fixed the problem with the loop nesting ...
There are three problems with this code:
while (!inputValid) {
System.out.print("How many integers? (Enter a positive integer): ");
try {
totalIntegers = input.nextInt();
inputValid = true;
} catch (NumberFormatException e) {
System.out.println("Invalid input!");
}
}
First problem is that you are catching the wrong exception. Read the javadoc.
The second problem is that if nextInt fails (due to a problem parsing the integer) it puts the scanner's input cursor back to where it was before the call. And when you call it again (in the next loop iteration) it will attempt to read same "bad" number again, and again, and again, ...
You have to tell the scanner to skip over the invalid line of input so that it can read the user's next attempt.
The third problem is that you don't check that the number you just read is positive!!
Final hint: consider using while (true) and a conditional break, instead of while (condition). I think it gives a more elegant solution.
#Kick Buttowski's solution deals with the bad input skipping by creating a new Scanner on each loop iteration. Apparently it works ... but I have some doubts1 that you can rely on this always working. IMO a better solution would be to use one Scanner throughout, and use a nextLine() call to read and discard the characters up to and including the end of line.
1 - My main concern is that when you leak a Scanner that it might (in some implementations) close the underlying input stream in a finalizer. If that actually happened, then the application would stop accepting input. The current implementation does not do this, but this is not clearly specified (AFAIK).
Your while loop really isn't doing anything for you in terms of stopping the user from advancing. You are able to hit the for loop because it is inside you while loop. Change your while loop and for loop so that the for loop is outside the while loop.
while (!inputValid)
{
System.out.print("How many integers shall we compare? (Enter a positive integer): ");
try {
totalIntegers = input.nextInt();
inputValid = true;
} catch (NumberFormatException e) {
System.out.println("Invalid input!");
}
} // End while //
/* Read in the candidates for smallest integer
* Validate this input as well, this time ensuring that the user has provided a valid int (any int will do at this point) and discarding any other data
*/
for (int ii = 1; ii <= totalIntegers; ii++) {
// Prompt
System.out.print("Enter value " + ii + ": ");
num = input.nextInt();
if (ii == 1) smallest = num;
else if (num < smallest) smallest = num;
} // End for //

How do I get this code to loop based off the user's input?

My code here checks whether or not the word that the user inputs is a palindrome or not. It executes properly its just that if the user tries to loop it by pressing "1". The program ends. How do I fix this?
int answer =0;
String original, backwards = "";
Scanner input = new Scanner(System.in);
System.out.println("A palindrome is a word that is the same forwards as it is backwards. Enter a word to check if it is a palindrome or not.");
original = input.nextLine();
int length = original.length();
do {
for ( int i = length - 1; i >= 0; i-- )
backwards = backwards + original.charAt(i);
if (original.equals(backwards))
System.out.println("The entered phrase is a palindrome.");
else
System.out.println("The entered phrase is not a palindrome.");
}
while (answer ==1);
System.out.println("If you would like to check another word press 1. If you wish to exit, press 2.");
answer = input.nextInt();
if (answer ==1){
System.out.println("Enter another word");
}
else if (answer == 2){
System.out.println("Have a nice day");
}
}
}
Here is a sample output of the program:
A palindrome is a word that is the same forwards as it is backwards. Enter a word to check if it is a palindrome or not.
racecar
The entered phrase is a palindrome.
If you would like to check another word press 1. If you wish to exit, press 2.
1
Enter another word
Your loop finishes before the user gets to choose if he wants to enter 1 or 2. It is a do...while loop, so it ends at the while. So it executes only once - because as soon as a palindrome is checked, the next thing is to check whether the answer is 1. But the user has not entered either 1 or 2 at this point.
So you should move the } while ( answer == 1 ) part to the line after the closing of the if...else... that checks what the user answer was.
Also, if the answer was 1, you should ask for another input. The only place you ask for input is before the loop starts. If the user answered 1 you should run original = input.nextLine(); again. Be careful - you may need to run two input.nextLine(), as the scanner will think the rest of the line after the 1 or 2 is what you meant.
Your scanner is asking for nextLine, but you're asking for an int. nextLine means it will take what is typed in the nextLine as a string.
Simple fix is replace 1 and 2 with characters a and b.
Complicated way is to parse string into integer.
make the palindrome check as a method and then call the method if the user input is 1.
In your code , it does not do anything if the user inout is equal to 1.
i just used your scanner objects as it is. You can declare them in your class to use it in all the methods.
public void palindrome(String S){
int answer =0;
String original, backwards = "";
Scanner input = new Scanner(System.in);
System.out.println("A palindrome is a word that is the same forwards as it is backwards. Enter a word to check if it is a palindrome or not.");
original = input.nextLine();
int length = original.length();
do {
for ( int i = length - 1; i >= 0; i-- )
backwards = backwards + original.charAt(i);
if (original.equals(backwards))
System.out.println("The entered phrase is a palindrome.");
else
System.out.println("The entered phrase is not a palindrome.");
}
while (answer ==1);
System.out.println("If you would like to check another word press 1. If you wish to exit, press 2.");
int option= input.nextInt();
if (option==1){
System.out.println("Enter another word");
String word= input.readLine();
palindrome(word);
}
You need to put the check if user want to enter another work in the while loop. But in the mean time, be careful to reset all variables to their original value, so it might be best to set them in the while loop as well. Something like this:
import java.util.Scanner;
public class Palidrome {
public static void main(String[] args) {
int answer = 0;
Scanner input = new Scanner(System.in);
String original;
System.out
.println("A palindrome is a word that is the same forwards as it is backwards. Enter a word to check if it is a palindrome or not.");
while( true ) {
original = input.nextLine();
String backwards = "";
int length = original.length();
for (int i = length - 1; i >= 0; i--)
backwards = backwards + original.charAt(i);
if (original.equals(backwards))
System.out.println("The entered phrase " + original + " is a palindrome.");
else
System.out.println("The entered phrase " + original + " is not a palindrome.");
System.out.println("If you wish to exit, press 2");
answer = input.nextInt();
if(answer == 2) {
System.out.println("Have a nice day");
break;
}
input.nextLine();
System.out.println("Enter another word");
}
input.close();
}
}
A do while loop works the same way as a regular while loop, except the first conditional check is omitted. If the condition in your while was met, then execution of the code in the do block would be continued. However, the while condition is never met, can you see why? Even if this condition was met, that's not the code you wanted executed next. The code below while is not a part of the do-while loop. You need to move the while to come after both of your conditional blocks at the end. The Java docs on while loops should be a useful read.

Reversing digits in Java. Leading and trailing zeros won't print

The problem was to reverse user entered digits. I have it working but while testing it I realized that it won't print either leading or trailing zeros.
For example if I enter 10 it only displays 1 in the result.
If I enter 0110 I get a result of 11.
Here is my code:
public class ReversingDigits {
int value;
int reverse;
public ReversingDigits() {
value = 10;
reverse = 0;
}// end constructor
public void reverse() {
System.out.println("Enter a valid 2-4 digit number: ");
Scanner input = new Scanner(System.in);
value = input.nextInt();
if (value < 10 || value > 9999){
System.out.print("Please enter a valid 2-4 digit number: ");
value = input.nextInt();
}
while (value > 0) {
reverse *= 10;
reverse += value % 10;
value /= 10;
}
System.out.println("Reversed numbers are: " + reverse);
}
}//end class
Any ideas on how to get the zeros to print?
Thanks
Make sure you work with a String while reversing your number. It will preserve leading zeros. As you know 00001 is the same as 1 when in int representation, and so converting that to a string will remove all leading zeros.
Here's your code sample modified to read a string from the input, and only convert it to an int when you need to check the range.
public void reverse() {
System.out.println("Enter a valid 2-4 digit number: ");
Scanner input = new Scanner(System.in);
String value = input.next();
int valueInt = Integer.parseInt(value);
if (valueInt < 10 || valueInt > 9999){
System.out.print("Please enter a valid 2-4 digit number: ")
value = input.next();
}
String valueReversed = new StringBuilder(value).reverse().toString();
System.out.println("Reversed numbers are: " + valueReversed);
}
Note that in your code, if a user enters the wrong range twice in a row, your program won't prompt him again. You may want to put this part of the code into a do-while loop which only exits when the input range is correct. Example
do {
System.out.print("Please enter a valid 2-4 digit number: ")
value = input.next();
int valueInt = Integer.parseInt(value);
} while (valueInt < 10 || valueInt > 9999);
//only get here when inputted value finally within target range.
Edit: As mentioned by #Levenal, you may also want to wrap Integer.parseInt in a try/catch block for NumberFormatException in the event the user passes in a non-numerical input.
As has been pointed out, reversing numbers you are much better off reversing a string. If you are allowed to stray away from console input, JOptionPane is quite good for simple String input, like so:
while(true){
String input = JOptionPane.showInputDialog("Please anter a number between 10 & 9999: ");
if(input == null){//If input cancelled
break; //Exit loop
} else if(input.matches("\\d{2,4}")){//Regex for at least 2 but no more than 4 numbers
System.out.println(new StringBuilder(input).reverse().toString());//Reverse
break;
}
}
Good luck!

Categories