Java passing scanner into method

2019-09-01 01:10发布

问题:

So I'm going through a bunch of basic programming ideas to help me get the hang of Java and I created a program that will print PI up to the 10th decimal place (and I can add more if I want).

However, I decided to go an extra step and create an option to keep running the program over and over until the user tells it to stop. I created a method to return either true (run again) or false (exit program). Originally I created a scanner in the method to take user input, and the program runs fine that way, but it tells me I have a resource leak because I didn't close the scanner in the method.

I have just passed the input scanner from main to the method as a parameter, but when I run the program it doesn't accept user input and will print out "Sorry, there was an error" (the else{} option in the if-else statement in my method). Now, I can go back and create a seperate scanner but my OCD doesn't want Eclipse telling me there is a resource leak (I think input.close() closes both scanners, but I am not sure).

Here is my code, I apologize to any Java enthusiasts who become smitten and offended at any bad practices I am unaware of, I am learning.

 import java.util.Scanner;
 import java.text.DecimalFormat;

 public class PiDecimalFormat {
     public static void main(String[] args) {
         Scanner input = new Scanner(System.in);
         DecimalFormat format = new DecimalFormat("#");
         int decPlace = 0;
         boolean runProgram = true;

         System.out.println("This program will print out PI to the decimal place of your choosing.");

         while (runProgram == true) {
             System.out.print("\nEnter the number of decimal places (up to 10) that \nyou would like to print PI to: ");
             decPlace = input.nextInt();

             switch (decPlace) {
                 case 0:
                     format = new DecimalFormat("#");
                     break;
                 case 1:
                     format = new DecimalFormat("#.#");
                     break;
                 case 2:
                     format = new DecimalFormat("#.##");
                     break;
                 case 3:
                     format = new DecimalFormat("#.###");
                     break;
                 case 4:
                     format = new DecimalFormat("#.####");
                     break;
                 case 5:
                     format = new DecimalFormat("#.#####");
                     break;
                 case 6:
                     format = new DecimalFormat("#.######");
                     break;
                 case 7:
                     format = new DecimalFormat("#.#######");
                     break;
                 case 8:
                     format = new DecimalFormat("#.########");
                     break;
                 case 9:
                     format = new DecimalFormat("#.#########");
                     break;
                 case 10:
                     format = new DecimalFormat("#.##########");
                     break;
             }

             System.out.println("\nThe value of PI to " + decPlace + " decimal places is " + format.format(Math.PI) + ".");

             runProgram = AskRunAgain(input);
         }

         input.close();
     }

     static boolean AskRunAgain(Scanner askUser) {
         String userChoice;

         System.out.print("\nWould you like to run the program again? [y/n]: ");
         userChoice = askUser.nextLine();

         if ((userChoice.equals("y")) || (userChoice.equals("Y")) || (userChoice.equals("yes")) || 
            (userChoice.equals("Yes")) || (userChoice.equals("YES"))) { 
             return true;
         }
         else if ((userChoice.equals("n")) || (userChoice.equals("N")) || (userChoice.equals("no")) || 
            (userChoice.equals("No")) || (userChoice.equals("NO"))) {
             System.out.println("\nExitting the program. have a good day!");
             return false;
         }
         else {
             System.out.println("Sorry, there was an error.");
             return false;
         }
     }
 }

If anyone could tell me why it is doing this, I would appreciate it. I'm new to Java (decent with C/C++/C# and Python). I didn't see other questions about this specific problem, and it's not a big deal if I just create another scanner in the method.

回答1:

I notice that you're doing this call:

decPlace = input.nextInt();

The return character isn't consumed, so it is still on the buffer as far as the Scanner is concerned.

This means, for an input of 2\n, it will read the 2 as the next integer, but read an empty string for the call to nextLine().

To get past this, finish consuming the line by using input.nextLine() after you read the next integer.

decPlace = input.nextInt();
input.nextLine();


回答2:

Just change and it will work.

askUser.nextLine();

TO

askUser.next();

static boolean AskRunAgain(Scanner askUser) {
        String userChoice;

        System.out.print("\nWould you like to run the program again? [y/n]: ");
        userChoice = askUser.next();