I am trying to do a do-while loop that makes the program iterate again after the user inputs "y" or "Y", but everytime i run the program, It prints out something like this:
Would you like to try again?
Enter Y for yes or N for no: [DrJava Input Box] (I enter y)
Are you a student? (no input box is shown, and it skips it)
Are you a member of staff or faculty? [DrJava Input Box] (i enter yes or no)
How many tickets do you need? [DrJava Input Box] (I enter an int, but it doesnt complete that part where it shows how many tickets sold or how much it costs)
Would you like to try again?
Enter Y for yes or N for no: [DrJava Input Box]
this is what my program looks like:
import java.util.Scanner;
public class Ticket
{
public static void main(String[] args)
{
Scanner keyboard = new Scanner(System.in);
double ticketprice = 12.00;
double result;
double result2;
double result3;
char repeat;
String input;
String student;
String staff;
int ticket;
do
{
System.out.println("Are you a student?");
student = keyboard.nextLine();
System.out.println("Are you a member of staff or faculty?");
staff = keyboard.nextLine();
System.out.println("How many tickets do you need?");
ticket = keyboard.nextInt();
if(student.equals("yes"))
{
System.out.println("Here is your " + ticket + " tickets for $0.00");
}
if(staff.equals("yes"))
{
result = ticketprice * .85;
result2 = ticket * result;
System.out.printf("Here are your " + ticket + " tickets for $%.2f\n", result2);
}
if(student.equals("no") && staff.equals("no"))
{
result3 = ticket * ticketprice;
System.out.printf("Here are your " + ticket + " tickets, for $%.2f\n", result3);
}
System.out.println("Would you like to try again?");
System.out.print("Enter Y for yes or N for no: ");
input = keyboard.next();
repeat = input.charAt(0);
}
while(repeat == 'y' || repeat == 'Y');
}
}
i am a beginner to programming, so any help would be good. Thank you.
At the end of the loop you call next() to read the "try again" response. This reads the next token, but still leaves the line ending on the input stream.
Next time through the loop, when you call nextLine() to read the "are you a student" response, it simply reads the remainder of that line immediately.
The easiest solution is:
Use nextLine() instead of next() for your "try again" prompt, but then this means you'll have to take care of the line ending left by nextInt() in the "tickets" question, so then you'll also have to...
Use nextLine() instead of nextInt() for your "tickets" question, then use Integer.parseInt() to parse the string into an int.
An alternate option, since all your responses seem to be just single-word responses, is to use next()/nextInt() everywhere and not use nextLine() at all. The point is, when you mix the two, you have to be aware of how they interact.
The issue lies in this block of code:
System.out.println("Would you like to try again?");
System.out.print("Enter Y for yes or N for no: ");
input = keyboard.next();
repeat = input.charAt(0);
When you call keyboard.next(), it doesn't read the entire line, so when your program loops again, the next time you call keyboard.nextLine(), it takes in part of what you entered previously in the loop and it gets ahead of itself.
The best solution would be to add a keyboard.nextLine() after you call keyboard.next() so that the remainder of the line will be consumed and won't be left over to mess up future iterations of the loop.
So for example you could change it like this:
System.out.println("Would you like to try again?");
System.out.print("Enter Y for yes or N for no: ");
input = keyboard.next();
keyboard.nextLine();
repeat = input.charAt(0);
Related
This question already has answers here:
Scanner is skipping nextLine() after using next() or nextFoo()?
(24 answers)
Closed 1 year ago.
The while loop should ask the user which option they would like to select, and after the option is complete it should go back to the start of the while loop. Right now, it only works correctly for the second else if, and nothing else.
while(flag){
System.out.println("Select an option from the menu below:" +
"\n1: Display consecutive numbers in a right triangle" + //needs better explanation
"\n2: Determine if a number is divisible by 3" +
"\n3: Determine the number of periods and spaces in a string" +
"\n4: Display a right triangle of astrisks" +
"\n5: Exit"); //better explanation
String option = input.nextLine();
if(option.equals("1")){ //does not work
System.out.println("Enter number of columns: ");
int width = input.nextInt();
while(width<=0 || width%1!=0){
System.out.println("Invalid input! Please enter a positive width.");
width = input.nextInt();
}
numOfColumns(width);
}
else if(option.equals("2")){ //does not work
System.out.println("Enter number:");
int num = input.nextInt();
divisibleBy3(Math.abs(num));
}
else if(option.equals("3")){ //works
System.out.println("Enter string:");
String sentence = input.nextLine();
System.out.println("Number of periods and spaces: " + periodsAndSpaces(sentence) + "\n");
}
else if(option.equals("4")){ //does not work
System.out.println("Enter the width of the triangle:");
int length = input.nextInt();
rightTriangle(length, "");
}
else if(option.equals("5")){ //exits the while loop
flag = false;
}
else{
System.out.println("That is not a valid option!");
}
}
For the if/else if statements indicated above, the program will execute the given method, then display the menu, followed by "That is not a valid input!", and then the menu again, even if the user has not entered anything.
As mentioned in comments, you need to consume the rest of the line after you use input.nextInt(); or any other method that does not consume the entire line, because it only takes the input of part of the line and the rest remains on the scanner. You can fix this by input.nextLine(); to advance past the current line so that it is ready for the next input when the while loop restarts, like so:
//Get a partial line input eg "nextInt()"
int someInput = input.nextInt();
//Consume the rest of the line
input.nextLine();
//Now process the input
...
Here is a working solution using the above technique:
if(option.equals("1")){ //does not work
System.out.println("Enter number of columns: ");
int width = input.nextInt();
//Consume the rest of the line
input.nextLine();
//Now process the input
while(width<=0 || width%1!=0){
System.out.println("Invalid input! Please enter a positive width.");
width = input.nextInt();
}
numOfColumns(width);
}
else if(option.equals("2")){ //does not work
System.out.println("Enter number:");
int num = input.nextInt();
//Consume the rest of the line
input.nextLine();
//Now process the input
divisibleBy3(Math.abs(num));
}
else if(option.equals("3")){ //works
System.out.println("Enter string:");
String sentence = input.nextLine();
System.out.println("Number of periods and spaces: " + periodsAndSpaces(sentence) + "\n");
}
else if(option.equals("4")){ //does not work
System.out.println("Enter the width of the triangle:");
int length = input.nextInt();
//Consume the rest of the line
input.nextLine();
//Now process the input
rightTriangle(length, "");
}
else if(option.equals("5")){ //exits the while loop
flag = false;
}
else{
System.out.println("That is not a valid option!");
}
This allows each option to work correctly.
I deduce that your input variable is a Scanner object.
Option number 3 is the only one that works as expected because it is the only one that uses nextLine() for the option-specific input, clearing the newline at the end of the input from the input buffer.
If someone selects option 1, and then enters 3, this is what happens:
input contains the string "3\n"
nextInt() reads 3
input still has "\n" in it that hasn't been read yet
numOfColumns(3) runs
The next iteration of the loop starts
It outputs the menu
nextLine() reads from input, immediately finds the \n that's still there from step 3, clears that character, and returns an empty string
option's value of "" falls through to the invalid input case
The loop starts over again
It outputs the menu
nextLine() waits for new input content to be available again
To get the behavior you were expecting, call input.nextLine() after each input.nextInt() call.
I'm trying to get a dice roller happening and I'm having some difficulty adding a loop somewhere so the program doesn't quit after one roll. I want to ask the user if they want to roll and it rolls by saying "y." I want to end the program by asking the user the same question but it ends with "n"
/*
Natasha Shorrock
Assignmnt A6
11/07/16
*/
package diceroller;
import java.util.Random;
import java.util.Scanner;
public class DiceRoller {
public static void main(String []args) {
System.out.println(" Do you want to roll the dice? ");
Random dice = new Random();
Scanner input = new Scanner(System.in);
int faces;
int result;
System.out.println("Dice Roller\n");
System.out.println("How many faces does the dice have?");
faces = input.nextInt();
result = dice.nextInt(faces) + 1;
System.out.println("\nThe dice rolled a " + result );
}//Dice Roller
}//class DiceRoller
You have to read the input after the following expression:
System.out.println(" Do you want to roll the dice? ");
To receive the users input call: input.nextLine();. Thereafter loop while the input is "y". If the user input is not equals to "y" the while-loop gets terminated.
The while(condition) loop is excuted as long as the condition is true
The while statement continually executes a block of statements while a particular condition is true. The while and do-while Statements
For example consider this code :
public static void main(String[] args) {
Random dice = new Random();
Scanner input = new Scanner(System.in);
System.out.println("Do you want to roll the dice? (y: yes / q: to quit)");
String answer = input.nextLine(); // reading the input
// we check if the answer is equals to "y" to execute the loop,
// if the answer is not equals to "y" the loop is not executed
while ("y".equals(answer)) {
System.out.println("Dice Roller");
System.out.println("How many faces does the dice have?");
int faces = input.nextInt();
int result = dice.nextInt(faces) + 1;
input.nextLine(); // to read the newline character (*)
System.out.println("The dice rolled a " + result);
System.out.println("Do you want to roll the dice? (y: yes / q: to quit)");
answer = input.nextLine();
}
}
To find out more about the while and do-while mechanisms, please visit this toturial
(*) To understand the use of nextLine() after a call to nextInt() please visit Scanner is skipping nextLine() after using next(), nextInt() or other nextFoo() methods
A do-while is a very good option. Another way of doing it could be using a while loop with a switch or preferably an IF/ ELSE IF statement. Perhaps something like below. This is only a suggestion.
boolean checkForExit = false;
while(checkForExit != true) { //while checkForExit does not equal true (therefore false) continue..
System.out.println("Do you want to roll the dice?");
String answer = input.next(); //get char input from user.
if(answer.toLowerCase().equals("y")) { //if 'y' then do this
//ask user for number of faces on dice and roll
} else { // otherwise end the program
//set isTrue to true to exit while loop. ends program
isTrue = true;
}
}
Is there a problem in my while or for loops by chance or am I missing something? First run through works fine but on the second I get this:
Enter course NAME: class name
Enter course HOURS: 4
Enter course GRADE: 4.0
You have entered class: jeff graves, class hours: 4 and, class grade 4.0
Do you want to continue:
y
Enter course NAME: Enter course HOURS:
It works just fine using (scanner).next(); but then I can only take one word from the user and it will throw an error from the nextInt when it rolls over.
public class GetGrades { //open class GetGrades
public static void main(String[] args) {
/**creating new instance of scanner named input to read user input*/
Scanner input = new Scanner(System.in); // create new instance of scanner object
boolean repeat = true; //boolean value for while loop holding array input
String s; // create string to store user input value for exiting loops
/** create 3 arrays to store course name, hours, and grades*/
String[] name = new String[20]; //type string array for class name
int[] hours = new int[20]; // type int array for class hours
float[] grade = new float[20]; //type float array for class grade
outerloop: // set break point for nested for loops exit on user input
while(repeat != false) {// while loop with boolean value to let user exit array input
for (int i=0; i<name.length; i++) { //for loop for name array
System.out.print("Enter course NAME: "); //prompt user for input
name[i] = input.nextLine(); //read next line value and store in array name
System.out.print("Enter course HOURS: "); //prompt user for input
hours[i] = input.nextInt(); //read the next int and store in array hours
System.out.print("Enter course GRADE: "); //prompt user for input
grade[i] = input.nextFloat(); //read the next float value and store in array grade
/**Print line to console summing um what the user has entered*/
System.out.println("You have entered class: " + name[i] + ", class hours: " + hours[i] +
" and, class grade " + grade[i]);
/**prompt user if wanted to enter more grades, break loop on n or N*/
System.out.println("Do you want to continue:");
s = input.next();
if ( s.equals("y") || s.equals("Y")) { //open if statement
repeat = true;
} else { //close if and open else
break outerloop;
} //close else statement
}//close for loop with i as count
}//close while
input.next() will read the next word. input.nextLine() will read up until the next time you press enter.
This means that when you write "y" and hit enter, you've input both a word "y", as well as the next enter, filling in both prompts at the same time and causing the next prompt to be written.
You can simply replace your next() with nextLine() when you ask to continue:
System.out.println("Do you want to continue:");
s = input.next();
becomes
System.out.println("Do you want to continue:");
s = input.nextLine();
thereby reading both the "y" and the enter. The next prompt is now free to accept new input.
When you input the grade, for example 12.3 and enter, "input.nextFloat();" will only take "12.3" but not "enter", so "enter" will be taken by the next scanner.
In my opinion,
first, change "s = input.next()" to "s = input.nextLine()", but it will take the "enter" of previous scanner "grade[i] = input.nextFloat();", so, second, put it into a while loop as a condition. like this
while((s = input.nextLine()).equals("")) {}
therefore, it won't stop til get the expect input.
try this..
System.out.print("Do you want to continue:");
while((s = input.nextLine()).equals("")) {}
if (s.equals("y") || s.equals("Y")) { // open if statement
repeat = true;
} else { // close if and open else
break outerloop;
} // close else statement
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.
System.out.print("Price of the book? ");
while (!keyboard.hasNextDouble() || priceOfBook <=0)
{
System.err.print("Invalid input - Price of " + bookTitle + "? ");
keyboard.nextLine();
}
priceOfBook = keyboard.nextDouble();
I am trying to validate the above code basically so that user can't enter negative numbers or letters or empty doubles but it's not working and I can't see where I'm going wrong. Can someone please help me?
So how i understand you need to real line until the user didint enter negative or letter.
Scanner sc = new Scanner(System.in);
double x = 0;
System.out.println("Enter price");
while (true) {
if (!sc.hasNextDouble()) {
System.out.println("Sorry price cant be negative or be letter");
break;
}
System.out.println("Enter price");
x = sc.nextDouble();
}
Hope it helps!
You put
priceOfBook = keyboard.nextDouble();
outside of your while loop :) Try like this:
while (priceOfBook <= 0)
{
System.err.print("Invalid input - Price of " + bookTitle + "? ");
priceOfBook = keyboard.nextDouble();
}
So that it will keep asking the user if he enters a number < 0.
You don't assign the user's input to priceOfBook until after the while loop. So, when your loop checks if priceOfBook is negative, it doesn't check the user's input, but the previously stored value (if there is one). This allows the user's input (even if it's negative) to pass the while loop, and then get saved as priceOfBook.
Try instead:
while (!keyboard.hasNextDouble() || priceOfBook = keyboard.nextDouble() <=0) {
System.err.print("Invalid input - Price of " + bookTitle + "? ");
keyboard.nextLine();
}