java


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


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 Links

Number Pattern Interruption
mappedBy reference an unknown target entity property - hibernate error maven annotation
Java program gets stuck while making HttpGet requests in a loop
Sending the DEFAULT placeholder via JDBC?
Windows can't run python script from within eclipse
Semaphores used for signaling in threads not working(concurrency issue)
Time complexity for a sorting algorithm
Remove all Rows Programmatically from TableLayout
Removing session attribute in jsp portlet issue in liferay
cucumber-Junit Assertion fails - It's not able to assert '£' sybmol
Java8 Collections.sort (sometimes) does not sort JPA returned lists
JScrollPane adding items Horizontally, but I want them added vertically
Refactoring code to respect OOP principles [closed]
Problems With SableCC Grammar File
java nested if statement else not working [duplicate]
recursion in java with unexpected output

Categories

HOME
ibm-bluemix
proxy
omnet++
path-finding
comparison
smarty
stock
office365api
analysis
cmd
amortized-analysis
youtube-api-v3
ios-charts
dacpac
export-to-csv
timeout
circular-dependency
hex-editors
django-admin
tostring
reactcsstransitiongroup
nhibernate-envers
object-detection
java-3d
realex-payments-api
bootstrap-tour
devops
claims-based-identity
autosys
rundeck
compatibility
phonegap
google-sites-2016
column-family
force-layout
host
main
impersonation
android-fingerprint-api
taffy
outlook-2013
chain-builder
worksheet
powercli
worker-thread
diagnostics
nodebb
account-kit
smart-table
root-framework
contact-list
multiple-regression
ready-api
testng-dataprovider
python-stackless
freedesktop.org
r-tree
qtableview
sailfish-os
clipperlib
e10s
apache-commons-net
relocation
mdt
cctv
device-manager
responsive-slides
starcluster
dealloc
android-2.2-froyo
sitemesh
tws
free-variable
angularjs-controller
simba
coderush
funscript
first-responder
cascalog
labwindows
asyncfileupload
gwt-ext
zpt
blackberry-playbook
psi
xtype
propagation
remember-me
suppress
getresponsestream
nhibernate.search
dbal
brewmp
sef
ctp4
phonon
scripting-languages
mdac

Resources

Database Users
RDBMS discuss
Database Dev&Adm
javascript
java
csharp
php
android
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App