返回主菜单时没有这样的元素异常

时间:2015-12-23 00:55:07

标签: java

我正在尝试制作一个使用一个类中的方法的货币转换程序。我已成功设法从mainMenu调用我的enterValues方法,但是当这个方法完成后,我需要它返回主菜单。调用mainMenu方法时,我收到以下NoSuchElement异常:

Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Unknown Source)
at Conversion.mainMenu(Conversion.java:25)
at Conversion.mainMenu(Conversion.java:34)
at Conversion.main(Conversion.java:63)

这是我的代码:

    import java.util.Scanner;
public class Conversion {

    int value;

    public void mainMenu() {
        int menuChoice;

        Scanner menuScan = new Scanner(System.in);

        System.out.println("1. Enter values and type -1 to stop");
        System.out.println("2. Euros");
        System.out.println("3. Dollars");
        System.out.println("4. Yen");
        System.out.println("5. Rupees");
        System.out.println("6. Exit");

        while (!menuScan.hasNextInt() || (menuChoice = menuScan.nextInt()) > 6) {
            menuScan.nextLine();
            System.err.println("Please enter a valid menu option 1 - 6: "); 
        }

        switch (menuChoice) {
        case 1:

            enterValues();
            mainMenu();

        case 2:

        }

    }

    public void enterValues() {

        Scanner valueScan = new Scanner(System.in);
        System.out.print("Enter value to convert: ");
        value = valueScan.nextInt();
        System.out.println("Value entered. Returning to main menu.");

        valueScan.close();

    }

    public static void main(String[] args) {

        Conversion conv = new Conversion();

        conv.mainMenu();

    }

}

2 个答案:

答案 0 :(得分:1)

您的代码存在几个风险问题:

  • 您在System.in之外创建了多个扫描程序,然后在关闭其他扫描程序之前关闭其中一个扫描程序,从而有可能关闭System.in。
  • 您在扫描程序中混合nextInt()nextLine()次调用,而无需先正确处理行尾令牌
  • 您在不想使用的情况下使用递归 - 自行调用方法。

建议:

  • 使用一台且只有一台基于System.in的扫描仪,在完成之前不要关闭它。
  • 将其传递给其他需要它的方法。
  • 每次拨打nextInt()时,请在处理行结束令牌后立即致电nextLine()
  • 不要在这里使用递归 - 有更好,更安全的方式重新调用主菜单。

答案 1 :(得分:1)

它与你制作System.in的1个以上对象有关。如果需要,您应该尝试仅使用一个,并且对您尝试阅读的元素使用正确的方法(在您的情况下为整数)。另外我会设计一个有点不同的类,一个while循环会更合适,你也不要在你的开关中调用break,导致它也执行case 2而不管wat。以下是一些示例代码供您使用:

public class Main {

    private int value;
    private int menuChoice;
    private Scanner menuScan;
    private boolean stop = false; // program stops when stop == true


    public static void main(String[] args){
        Main main = new Main();
        main.runProgram();
    }

    public void printMenu() {
        System.out.println("Enter values and type -1 to stop");
        System.out.println("1. Euros");
        System.out.println("2. Dollars");
        System.out.println("3. Yen");
        System.out.println("4. Rupees");
        System.out.println("5. Exit");
    }

    public void runProgram() {
        stop = false;
        menuScan = new Scanner(System.in);
        do {
            printMenu();
            menuChoice = menuScan.nextInt();
            switch(menuChoice){
                case 1:
                    enterValues("Euro"); // enter the values and give it a string with the type of value that is being entered, so you can check for this later
                    break;
                case 2:
                    enterValues("Dollar");
                    break;
                case 3:
                    enterValues("Yen");
                    break;
                case 4:
                    enterValues("Rupees");
                    break;
                case 5:
                    System.out.println("Stopping program");
                    stop = true;
                    break;
                default:
                    System.out.println("Please enter a valid number");
                    break;
            }
        }while(!stop);
    }

    public void enterValues(String valueType) {
        System.out.print("Enter value to convert: ");
        value = menuScan.nextInt();
        System.out.println("Value entered. - run your conversion now. (Returning to main menu for now)");
        /////// run your conversion here or create a method for this and call it now.
    }

}

注意我只使用了1个类范围的System.in,并且没有主菜单的递归,它全部在循环中。