import java.util.Scanner;
import java.util.InputMismatchException;

/**
 * Demonstrates potential problems from alternating between Scanner's
 * nextLine() and nextDouble().  Specifically, this program reads in
 * a string and then a number from the user, continuing until the user
 * enters nothing for the string.
 *
 * (Note that if you read in everything with nextLine() and
 * then use parseDouble(), you won't have to deal with this.)
 *
 * @author Zach Tomaszewski
 * @version 12 Mar 2009
 */
public class InputTrouble {

  public static void main(String[] args) {

    Scanner keybd = new Scanner(System.in);

    //continue reading in input until the user enters nothing
    boolean keepAsking = true;
    while (keepAsking) {

      System.out.print("Enter a string (or nothing to stop): ");

      // The user will now enter a string here, followed by a \n (Enter).
      // All of this will be read in by nextLine(), leaving nothing in the
      // input stream.  So no problems here...
      String input = keybd.nextLine();

      if (input.equals("")) {
        //nothing entered for the string, so quit
        keepAsking = false;

      }else {
        //user entered a string, so print it:
        System.out.println("You entered the string: " + input);

        //now the user needs to enter a number
        //keep going until they get it right...
        boolean gotNumber = false;
        while (!gotNumber) {
          try {
            System.out.print("Enter a number: ");

            // The user will now type something and hit enter. If the user
            // enters a number, nextDouble() will read it in, but will still
            // leave the \n.  This \n would cause problems when we return
            // to the top of the outer while loop, as nextLine() would then
            // not wait to let the user enter anything and would read in
            // an empty string.  (However, if we were only reading in a series
            // of doubles, it wouldn't be a problem after all, because
            // nextDouble() skips over preceding white space, such as \n)
            //
            // Similarly, if the user enters something other than a number,
            // the program will be put into an infinite loop because the
            // "garbage" (letters) is never cleared out of the input stream.
            // See below for the simple fix to both of these problems.
            double number = keybd.nextDouble();
            System.out.println("You entered the number: " + number);
            gotNumber = true;
          }catch (InputMismatchException ime) {
            System.out.println("That was not a number.  Try again.");
          }

          // This next line will remove anything left over in the input stream
          // after nextDouble() before prompting the user again for any input.
          //
          // To see the point of this entire example, remove (or comment out)
          // the following line.  Then run the program and try the following:
          //  1) Enter a string and then a number
          //  2) Enter a string and then a number, a space, and a word
          //     (such as "3 miles" when prompted for a number).
          //  3) Enter a string and then a string
          // See what happens in each case and trace through the code to be
          // sure you understand why.  Now put the line below back in and
          // see how it fixes all the above problems.
          keybd.nextLine();  //clear input stream
        }
        System.out.println();
      }//end else
    }
  }//end main

}//end class

