-2

What seems fairly simple has got me completely confused. I ask the user for some inputs at the beginning of a while loop to be able to execute a program inside the loop. After the program is executed, I want to prompt the user at the end of the loop to restart or end the loop.

I am trying to make the loop ask only the LAST question after it has completed the program within it. Then, if the user has answered "yes", the loop will restart. Any other answer will result in ending the loop.

Here is my code

String rerun = null;
boolean run = true;
int x;
int y;

while (run = true)
        {
            // first question
            x = keyboard.nextInt();
            y = keyboard.nextInt();

            // run program with x and y


            // second question (ask to continue)
            rerun = keyboard.nextLine();

            if (rerun.equalsIgnoreCase("yes"))
            {
                continue;
            }
            else
            {
                run = false;
                //break; stops the loop without answering the second question
            }


        }

Sample input/output:

Enter height and width of the house you want me to draw: 4 4

Program runs...

Bob, do you want me to draw another house for you (yes to continue)?
Enter height and width of the house you want me to draw (must be even numbers):

Why is it asking me the height and width again even though I have conditions at the end, prohibiting the loop to restart before I prompt it to continue?

Thank you!

Philippe
  • 23
  • 1
  • 5
  • Don't forget to call `keyboard.nextLine()` after `y = keyboard.nextInt();`. This will swallow the end of line character which `nextInt()` is not able to do. – Hovercraft Full Of Eels Oct 15 '15 at 00:43
  • I don't mind that I need to input the integers on the same line. I am trying to make the loop ask me only the last question. – Philippe Oct 15 '15 at 00:48
  • Please try it and find out. – Hovercraft Full Of Eels Oct 15 '15 at 00:49
  • It is not what I am trying to do. I want the user to be prompted to answer the last question only after the program inside the loop has been executed. Then, based of their answer, decided to restart or end the loop. (Question clarified) – Philippe Oct 15 '15 at 00:59
  • "the program outputs both questions at the beginning of the loop AND at the end of the loop" Well that would be because you ask both questions inside the loop. If you don't want to ask the first question repeatedly, move it outside the loop. – Boann Oct 15 '15 at 01:29
  • But if I move it outside of the loop and the user chooses to redo the loop, the question wouldn't appear since it is outside of the loop, and the program within it would not be able to run -.- – Philippe Oct 15 '15 at 02:40
  • Right, it won't appear the subsequent times. That's specifically what you ask for in your question, twice! Is that not what you want? P.S. After your recent edit, you now have `while (run = true)`, instead of `while (run == true)`, which means the `run` variable's value is always reset to true. Maybe that has something to do with whatever it is you're asking for. – Boann Oct 15 '15 at 03:42
  • I don't think it matters in the context of what I am trying to achieve. Anyways, I needed a do-while loop. Thank you for your help! – Philippe Oct 15 '15 at 04:24

3 Answers3

0

Try this.

I haven't changed your code much, but I've printed a prompt on the screen before asking for a user input and printed the user input on the screen before restarting the loop. You could also do a try and catch block as below and see where the exception occurs. Also this would help in cause if a user enters a String instead of int for x or y.

import java.util.Scanner;

public class Test {

public static void main(String args[]) {

    String rerun = null;
    boolean run = true;
    Scanner keyboard = new Scanner(System.in);

    while (run == true) {

        int x = 0;
        int y = 0;
        String val = "";

        System.out.print("Enter x int : ");
        try {
            x = keyboard.nextInt();
        }
        catch (Exception ex) {

            System.out.println("Error at x : " + ex.getMessage());
        }
        System.out.print("Enter x int : ");
        try {
            y = keyboard.nextInt();
        }
        catch (Exception ex) {

            System.out.println("Error at y : " + ex.getMessage());
        }
        System.out.print("Enter string : ");
        try {
            val = keyboard.nextLine();
        }
        catch (Exception ex) {

            System.out.println("Error at string: " + ex.getMessage());
        }
        System.out.println("x : " + x + ", y : " + y + ", val : " + val);
    }
}

}
Achintha Gunasekara
  • 1,137
  • 1
  • 14
  • 28
  • Apologies, I added an explanation above. – Achintha Gunasekara Oct 15 '15 at 01:01
  • This is too complicated for me at the moment. I am going to try a switch statement first. – Philippe Oct 15 '15 at 01:07
  • It's basically your code. Only major changes are the try and catch blocks. They catch the errors thrown by the code without crashing the application. Have a look at https://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html and https://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html – Achintha Gunasekara Oct 15 '15 at 01:09
0

From your question it looks as though you want the loop to run at least once before the test. If that's the case then a do while loop is probably more appropriate than a while loop.

A do while loop looks something like:

do {
     int x = keyboard.getInt();
     int y = keyboard.getInt();
     // process
     System.out.println("Do you want to continue?");
} while (keyboard.nextLine().equalsIgnoreCase("yes"));

That seems to me to capture your intent better than the while loop of your original code and avoids having a keepRunning boolean (which I find confusing to read).

If you find the while statement confusing, rather than going back to a boolean variable, you can split the test into a separate method:

do {
    ...
} while (shouldRepeat());

private boolean shouldRepeat() {
    System.out.println("Do you wish to continue?");
    String answer = keyboard.nextLine();
    return answer.equalsIgnoreCase("yes");
}

In my view that is still a clearer and less fragile solution than having a flag that is set.

sprinter
  • 24,103
  • 5
  • 40
  • 71
0

The problem is that after you use the nextInt() method the 'end of line' character is still in the input buffer. You must manually flush the buffer by calling nextLine(). I have modified your code below to show how you can fix this.

        // first question
        x = keyboard.nextInt();
        y = keyboard.nextInt();

        // run program with x and y

       //Flush Input Buffer
       keyboard.nextLine();

        // second question (ask to continue)
        rerun = keyboard.nextLine();
Daniel Maclam
  • 111
  • 1
  • 6