1

I am trying to make a currency conversion program which uses methods in one class. I have successfully managed to call my enterValues method from the mainMenu but when this method has finished, I need it to go back to the main menu. I receive the following NoSuchElement exception when calling my mainMenu method:

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)

Here is my code:

    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();

    }

}
James B
  • 221
  • 3
  • 14
  • Can you point out which are the lines identified in the stack trace, and what you supplied for input? – Scott Hunter Dec 23 '15 at 00:59
  • Possible duplicate of [java.util.NoSuchElementException - Scanner reading user input](http://stackoverflow.com/questions/13042008/java-util-nosuchelementexception-scanner-reading-user-input) – Tom Dec 23 '15 at 02:14

2 Answers2

1

Several issues at risk with your code:

  • You're creating more than one Scanner off of System.in and then closing one of them before you're done with the other Scanners, risking closing System.in.
  • You're mixing nextInt() with nextLine() calls on the Scanner without first handling the end of line token properly
  • You're using recursion where you don't want to use it -- having a method call itself.

Suggestions:

  • Use one and only one Scanner based on System.in and don't close it until your done.
  • Pass it into other methods that need it.
  • Every time you call nextInt() on it, call nextLine() too immediately after to handle the end of line token.
  • Don't use recursion here -- there are better and safer ways to re-call the main menu.
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • Thank you i'll be sure to follow your suggestions, can I ask what a better way to re-call the main menu would be? – James B Dec 23 '15 at 01:04
1

It has to do with you making more then 1 objects of your System.in. You should try to use only one if needed, and also use the correct method for the element youre trying to read (integers in your case). Also i would design the class a little different, a do while loop would be more appropriate, you also dont call break in your switch, causing it to also execute case 2 no matter wat. Here is some sample code for you to work with:

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.
    }

}

note i only used 1 class scoped System.in and no recursion for the main menu, its all in the loop.

Eksit
  • 62
  • 5