I have a boolean Guess function:
public boolean guess() {
String checkInput = scanner.nextLine();
try {
guess = Integer.parseInt(checkInput);
} catch (NumberFormatException e) {
return false;
}
return true;
}
which is called by another function in a do while loop:
while (!player.guess()) {
player.guess();
}
If I enter an int, the program runs properly and terminates. But if input is a non-int character, the program gets stuck in the while loop. I don't know what's going on here.
Your guess function is designed that way.
It returns false if the input is not numeric (catch). So it stays in the loop until you input a numeric value.
Another problem is that you are calling the function twice every loop (once on the loop condition check and another inside the loop). So if you type a non numeric character on the first (loop condition) and a numeric on the second (inside the loop) it will still ask for an input a third time.
I don't know what your intention is but you probably would want something like:
while (!player.guess()) {
continue;
}
Unless you really want it to be called twice.
Your scanner.nextLine() reads the line forever, it doesn't ask for another input.
while (!player.guess()) { // Entered Integer. (!true) and loop breaks
player.guess();
}
while (!player.guess()) { // Entered Non-Integer. (!false) and program enters the loop
player.guess(); // You are not storing the result in some boolean variable
//Therefore, it doesn't matter whether true or false
//while (!player.guess()) will be checked once again
}
SOLUTION:
boolean flag = player.guess(); // capture the result
while (!flag) { // verify the result
flag = player.guess(); // capture the result again
}
Related
But if I put it to "valid = false;" it does not work in debug or running.
In fact even running the code, I can't type anything after the "Do you want to order anything else?", no matter if it's in debug or running mode.
Am I missing something? After asking "how many you want to order" and you put in a number after it should ask "do you want to order anything else" which is does but then I can't type and break out of the do while loop. Everything else is working up to that point.
do {
boolean itemValid = true;
while (itemValid) {
System.out.println("Please enter an item name: ");
String enterItem = scnr.nextLine();
if (keepTrack.containsKey(enterItem)) {
System.out.println(keepTrack.get(enterItem));
itemValid = false;
} else {
System.out.println("Sorry we don't exist.");
continue;
}
System.out.println("How many do you want to order?");
int enterQuan = scnr.nextInt();
yourOrder = enterQuan;
valid = false;
}
System.out.println("Do you want to order anything else?");
String yesNo = scnr.nextLine();
if (yesNo.equalsIgnoreCase("n")) {
valid = false;
} else
break;
} while (valid);
Two problems with your code. First, probably unnoticed yet:
do ...
if (keepTrack.containsKey(enterItem)) {
System.out.println(keepTrack.get(enterItem));
itemValid = false;
} else {
System.out.println("Sorry we don't exist.");
continue;
}
When your input is "invalid", you turn into the else branch. The else branch continues the loop. The loop depends on value. Thus: as soon as you start with value=true, and then have an invalid input, you end up with a never-ending loop. Because nothing between the loop start and the continue statement will ever change the conditions that would end the loop.
Your actual question: when you call int enterQuan = scnr.nextInt() that does not consume the "ENTER" that you typed on the console. See here for details.
And there is another problem:
if (yesNo.equalsIgnoreCase("n")) {
valid = false;
} else
break;
}
When the user enters n or N, you go valid=false which ends the outer do-while loop. Thus: when the user enters anything else, the elsepath is taken. What is to be found in the else path? A break. Which also ends the do-while loop.
In other words: your code does exactly what you told it to do: to end the do-while loop, one way or the other.
The real answer is: you need to be much more careful what you put in your code. Each and any character matters. And when you put something into your code for an experiment: remember that it is there, and has effects.
I'm trying to use for loops to check if a user is inputting an integer. The code will not let the user pass unless it is given an integer. I'm going to post a portion of my code, but if you think the error is outside of what I posted, I'll post the rest:
error:
not a statement
Code:
for (int prompt = 1; prompt < mainarray.length; prompt++) {
System.out.println("Please enter #" + prompt);
checkint = scan.nextInt();
// The error is pointing to the != in the following loop.
//I have check int declared above this code.
for (checkint != (int) checkint) {
System.out.println("This is not an integer, please input an integer");
}
mainarray[prompt] = checkint;
System.out.println("Number has been added\n");
}
You need an If statement to check this, not a for loop
if(checkint != (int)checkint)
{
System.out.println("This is not an integer, please input an integer");
}
Edit:
The Op said he/she is getting error as: java.util.InputMismatchException:null (in java.util.Scanner)
Solution:
You are using nextInt();. The java.util.Scanner.nextInt() method Scans the next token of the input as an int. if the next token does not match the Integer regular expression, or is out of range it will throw InputMismatchException.
You can use this code
Scanner scan = new Scanner(System.in);
String s = scan.nextLine();
try{
val = Integer.parseInt(s);
}
catch(NumberFormatException ex){
System.out.println("This is not an integer, please input an integer");
}
Even better,
try{
checkint = scan.nextInt();
}
catch(Exception ex){
System.out.println("This is not an integer, please input an integer");
}
Edit2
try
{
checkint = scan.nextInt();
mainarray[prompt]=checkint;
}
catch(Exception ex)
{
System.out.println("An integer is required;" + "input an integer please");
}
for(checkint != (int)checkint)
Isn't valid syntax for a for loop. That's a while loop. Consider this:
while (checkint != (int)checkint)
A while loop has one condition and will loop until that condition is not met. A for loop is actually just a while loop in disguise, but has three conditions:
starting point/initialization; condition; increment
However, you can leave the starting point and the increment blank to simulate a while loop.
HOWEVER this will put you in an ENDLESS LOOP. I don't know why you want a loop in the first place:
Finally, you should actually be doing this:
if (checkint != (int)checkint)
Change
for(checkint != (int)checkint)
as
for(;checkint != (int)checkint;)
From Doc
The general form of the for statement can be expressed as follows:
for (initialization; termination; increment) {
statement(s)
}
The initialization expression initializes the loop; it's executed
once, as the loop begins.
When the termination expression evaluates to false, the loop
terminates.
The increment expression is invoked after each iteration through the
loop; it is perfectly acceptable for this expression to increment or
decrement a value.
BUT this will leads to an infinite loop in your code. So change it as
if (checkint != (int)checkint)
I am a newbee in the Java world. I wrote this program which reads in string array... When I run it, it never stops?!! what shall I add /change to make it end scanning?
import java.util.*;
public class Ex21 {
public static void main(String[] args) {
int i, n = 5;
String c;
ArrayList<String>words = new ArrayList<>();
System.out.println("Enter multi strings: ");
Scanner input = new Scanner(System.in);
boolean loop = true;
while(loop) {
words.add(input.next());
Collections.sort(words);
System.out.println("The sorted list is: " + words);
}
}
}
A while loop by definition continues executing its body until its condition (in this case the variable loop) evaluates to false. You never set loop to false in the body of the while-loop, hence the condition will never evaluate to false and the loop will never end.
Additionally, it seems like you want to sort a list of words entered by the user. I wouldn't advise calling Collections.sort on every iteration of the loop. Maybe look into using a data structure that keeps its elements sorted on its own, such as a TreeSet. Or, at least, only call the sort method once, directly after the loop.
while(condition) {
/* do something */
}
means /* do something */ happens unless condition == false, in your case it alwats true, that is why it doesn't stop. So Java behaves ok in your case.
while(loop) with loop always having the value true in your program is a so called endless loop, as the name says it never ends and this is what you are experiencing.
To make a loop stop you have to set the value of loop to false if some condition is fulfilled or terminate the loop using the key word break.
A condition may be for example having a certain word witch lets your loop terminate when it is entered, something like "exit"
Here is an example how you could set loop to false
String word = input.next();
boolean loop = ! "exit".equalsIgnoreCase(word);
while (loop) {
words.add(word);
Collections.sort(words);
System.out.println("The sorted list is: " + words);
word = input.next();
loop = ! "exit".equalsIgnoreCase(word);
}
System.out.println("Bye!");
Here is an other example how you could cancel the loop using break
while (true) {
String word = input.next();
if("exit".equalsIgnoreCase(word)) {
break;
}
words.add(word);
Collections.sort(words);
System.out.println("The sorted list is: " + words);
}
System.out.println("Bye!");
Note that the word exit is banned from the set that your arraylist can contain, You can change the program though to have it saved too.
Here is my method:
//usedLetters method to check if user's guess has already been guessed
private boolean usedLetters(char used[], char alphabet) throws IOException
{
for(int x=0; x<used.length; x++){
if(alphabet == used[x])
{
return true;
}
else
{
used[dataSize] = alphabet;
return false;
}
}
}//End of usedLetters method
IT checks to see if the alphabet that the user entered in an another method has already been guessed. If it has already been guessed, it returns true, and if has not been already guessed, it adds the alphabet into used, and returns false. But the error says that there are no return statements...I am not familiar with methods in general, so I am confused. Any help would be appreciated!
What if used.length==0? Then the for-loop is never entered.
Therefore you need a return statement after the loop.
What if the for is never entered? i.e. used.length == 0 (used is an empty array). In this case - nothing will be returned.
The compiler forbids a flow that can terminate without returning the value, and that's why it shows the error.
Also note, I believe even after fixing this issue - the program will yield a wrong result, it will only check the first element of used, without advancing to the next one.
You should move the return false; to just before the last }. Otherwise it will return in the first iteration of the loop.
/usedLetters method to check if user's guess has already been guessed
private boolean usedLetters(char used[], char alphabet) throws IOException
{
for(int x=0; x
if(alphabet == used[x])
{
return true;
}
else
{
used[dataSize] = alphabet;
return false;
}
}
}//End of usedLetters method
There should be return statement after for loop, currently there is no return statement that's why you are getting error.
As you have written your code, the method will always return on the first iteration of the cycle, while I doubt this is what you want.
I believe that you should return false outside the for. I am not sure what does to "guess an alphabet" mean but I think this is what you are trying to do.
Yep, all the above are correct. You would be better off defining the return variable at the top, setting it to values wherever you need to within the method body, breaking out of the 'for' loop and returning it once at the end.
I'm trying to input 3 different variables into an array inside a while loop, as long as i don't enter stop for any of the variables. the while loop is only suppose to let me input a second variable value if the 1st variable isn't stop, and likewise with inputting a third variable value
Right now, the first loop goes fine and i can input all 3 variables, but the 2nd and 3rd time, the for loop outputs the first variable, but doesn't allow me to input a value before skipping to the 2nd variable.
ex of what i mean:
name:afasdf
extra info:afdsaf
unit cost:123123214
name: extra info: adflskjflk
also, entering Stop isn't ending the loop either
unit cost:123217
i know that this loop works when there's only one variable, and i've tried using a for loop instead of a while loop, and adding tons and tons of else statements, but it seems to stay the same
is there something wrong with the way i set up my breakers?
is the way i set up the last breaker(the one that stops even when i put stop for a double variable) messing up the rest of hte loop?
thank you so much
here is my code
ArrayItem s = new ArrayItem();
String Name = null, ID = null;
double Money = 0;
boolean breaker = false;
while(breaker ==false)
{
System.out.print("Name:" + "\t");
Name = Input.nextLine();
if(Name.equals("Stop")) //see if the program should stop
breaker = true;
System.out.print("Extra Info:" + "\t");
Details = Input.nextLine();
if(ID.equals("Stop"))
breaker = true;
System.out.print("Unit Cost:" + "\t");
Money = Input.nextDouble();
// suppose to let me stop even if i input stop
// when the variable is suppose to be a double
if(Input.equals("stop") || Input.equals("stop"))
breaker = true;
else
s.SetNames(Name);
s.SetInfo(Details);
s.SetCost(Money);
}
A couple of things about the code: "Name:" + "\t" can be simplified ot "Name:\t". This is true for the rest of the code. In Java, it's customary to use camelcase where the first word is lowercase. For example, s.SetMoney would be s.setMoney. Also, variables follow the same rules where Money would be money, and ID would be id. If your teacher is teaching you otherwise, then follow their style.
The loop should also be a do-while loop:
do
{
// read each value in sequence, and then check to see if you should stop
// you can/should simplify this into a function that returns the object
// that returns null if the value should stop (requiring a capital D
// double for the return type)
if ( /* reason to stop */)
{
break;
}
s.setNames(name);
s.setId(id);
s.setMoney(money);
} while (true);
private String getString(Scanner input)
{
String result = input.nextLine();
// look for STOP
if (result.equalsIgnoreCase("stop"))
{
result = null;
}
return result;
}
private Double getDouble(Scanner input)
{
Double result = null;
// read the line is a string looking for STOP
String line = getString(input);
// null if it's STOP
if (line != null)
{
try
{
result = Double.parseDouble(line);
}
catch (NumberFormatException e)
{
// not a valid number, but not STOP either!
}
}
return result;
}
There are a lot of concepts in there, but they should help as you progress. I'll let you put the pieces together.
Also, you did need to fix the brackets, but that's not the only issue. Because Money is a double, you must read the value as a String. I suspect that Input is a Scanner object, so you can check Input.hasNextDouble() if it's not, then you can conditionally check the String value to see if it's "stop" (note: you are checking for "Stop" and "stop", which are not equal). Your last, no-chances check compares the Scanner to "stop", which will never be true. Check
System.out.print("Unit Cost:\t");
if (Input.hasNextDouble())
{
Money = Input.nextDouble();
// you can now set your object
// ...
}
// it's not a double; look for "stop"
else if (Input.nextLine().equalsIgnoreCase("stop"))
{
// exit loop
break;
}
// NOTE: if it's NOT a double or stop, then you have NOT exited
// and you have not set money
breaker = true;
while(breaker){
Name = readInput("Name");
Details = readInput("Details");
Money = Double.parseDouble(readInput("Money"));
if(Name.equals("stop") || Details.equals("stop"))
breaker = false;
else {
// set ArrayItem
}
}
private static String readInput(String title){
System.out.println(title+":");
//... read input
// return value
}