2

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.

Jason C
  • 34,234
  • 12
  • 103
  • 151
  • possible duplicate of [Skipping nextLine() after use nextInt()](http://stackoverflow.com/questions/13102045/skipping-nextline-after-use-nextint) – Jason C Mar 31 '14 at 00:00

2 Answers2

0

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.

Jason C
  • 34,234
  • 12
  • 103
  • 151
  • see i tried that originally, but when i did i would get an error that looks like this. java.lang.StringIndexOutOfBoundsException: String index out of range: 0 at java.lang.String.charAt(Unknown Source) at Ticket.main(Ticket.java:59) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:272) – user3479350 Mar 30 '14 at 23:53
  • @user3479350 Sorry, see edit. You'll have the same problem with `nextInt()` -> `nextLine()`. You'll have to make one more change. – Jason C Mar 30 '14 at 23:56
  • @user3479350 Yes that would explain that error, as `nextInt()` also just consumes the int but leaves the line ending, then `nextLine()` reads an empty string (the remainder of the line) of length 0, then `.charAt(0)` is consequently out of range. Incidentally, you probably also want to check to make sure the string has at least one character in it before attempting to access `.charAt(0)`; even after you fix your issues, you don't want it to crash if the user just types "enter" without entering anything. – Jason C Mar 30 '14 at 23:57
0

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);
Andy Niles
  • 36
  • 3