Reputation: 469
I'm working on a math training program of sorts. I'm trying to implement a for loop so that each question type that the user picks will generate three questions. This works perfectly if the user enters the correct variable type. However, if a user enters the wrong variable/ variable type what happens is that it loops in an odd way. It's hard to explain but if you take the code and try giving it the wrong input you will soon see. I'm not sure how this may be caused so I figured I'd post here. I've commented out so that only one operation type (addition) is available, just for debugging purposes. If you type something other than what the program expects you will see. I'm quite new to loops and have tried my best at multiple ideas but I'm coming up short. Thank you!
// Welcome
System.out.println("Hello and welcome to the Math Trainer!\n======================================");
System.out.println("Which math operation would you like to practice?");
// Print options to select from
System.out.println(" " + "[A]ddition");
System.out.println(" " +"[S]ubtraction");
System.out.println(" " + "[M]ultiplication");
System.out.println(" " + "[D]ivision");
System.out.println(" " + "[R]emainder");
// Ask for user input on which to choose
System.out.print("Enter your choice:" + " ");
String userLetter = stdin.nextLine();
// Calculate random values from seed and shift them within range
for(int count = 0; count < Config.NUMBER_OF_QUESTIONS; count++){
int ran1 = randGen.nextInt(Config.MAX_VALUE - Config.MIN_VALUE + 1);
int ran2 = randGen.nextInt(Config.MAX_VALUE - Config.MIN_VALUE + 1);
int ran1Shift = ran1 + Config.MIN_VALUE;
int ran2Shift = ran2 + Config.MIN_VALUE;
// Initialize different answers per operation
double additionAnswer = (double)ran1Shift + ran2Shift;
double subtractionAnswer = (double)ran1Shift - ran2Shift;
double multiplicationAnswer = (double)ran1Shift * ran2Shift;
double divisionAnswer = (double)ran1Shift / ran2Shift;
double remainderAnswer = (double)ran1Shift % ran2Shift;
// Prompt user with a question based upon random numbers and operation selection
// Presentation of addition problems
if(userLetter.equalsIgnoreCase("a")) {
System.out.print("What is the solution to the problem:" + " " + ran1Shift + " " + "+" + " " + ran2Shift + " = ");
if (stdin.hasNextDouble()) {
double userNum = stdin.nextDouble();
if (userNum == additionAnswer) {
System.out.println("That is correct!");
} else {
System.out.println("The correct solution is: " + additionAnswer + ".");
}
} else {
System.out.println("All solutions must be entered as decimal numbers.");
System.out.println("The correct solution is " + additionAnswer + ".");
}
}
else{
System.out.println("I'm sorry, I only understand choices of: A, S, M, D, or R!");
}
}
// Program exit
System.out.println("======================================");
System.out.println("Thank you for using the Math Trainer!");
}
}
Upvotes: 1
Views: 121
Reputation: 159114
If I enter 'z' instead of a, s , m, d, or r, for example, the program prints the else statement 3 times.
Assuming that 3 times is because Config.NUMBER_OF_QUESTIONS
is 3, it is because you execute String userLetter = stdin.nextLine();
outside the loop, so the value of userLetter
never changes.
If you fix the indentation of your code, so the scope of the for
loop becomes clear, you'll see that you need to move the following lines inside the loop:
// Ask for user input on which to choose
System.out.print("Enter your choice:" + " ");
String userLetter = stdin.nextLine();
Original Answer
hasNextDouble()
doesn't consume anything, so when you ask a question, and user responds I don't know
instead of typing a number, the text stays.
When you then ask the next question, the (bad) answer from previous question is still in the buffer, and the system will fail the next hasNextDouble()
call too, and so on, and so on, ...
This is one of the main flaws with how people use the Scanner
. They forget error handling.
In this case, answers are give one per line, so any time you read an answer, you should always call nextLine()
afterwards, to discard any extra text after the answer, or to discard the entire line if bad input was given.
Upvotes: 1