java.util.NoSuchElementException - Scanner reading user input

input, java, java.util.scanner, nosuchelementexception

Solution

This has really puzzled me for a while but this is what I found in the end.

When you call, `sc.close()` in first method, it not only closes your scanner but closes your `System.in` input stream as well. You can verify it by printing its status at very top of the second method as :

    System.out.println(System.in.available());

So, now when you re-instantiate, `Scanner` in second method, it doesn't find any open `System.in` stream and hence the exception.

I doubt if there is any way out to reopen `System.in` because:

`public void close() throws IOException --> Closes this input stream and releases any system resources associated with this stream. The general contract of close is that it closes the input stream. A closed stream cannot perform input operations and **cannot be reopened.**`

The only good solution for your problem is to initiate the `Scanner` in your main method, pass that as argument in your two methods, and close it again in your main method e.g.:

`main` method related code block:

Scanner scanner = new Scanner(System.in);  

// Ask users for quantities 
PromptCustomerQty(customer, ProductList, scanner );

// Ask user for payment method
PromptCustomerPayment(customer, scanner );

//close the scanner 
scanner.close();

Your Methods:

 public static void PromptCustomerQty(Customer customer, 
                             ArrayList<Product> ProductList, Scanner scanner) {

    // no more scanner instantiation
    ...
    // no more scanner close
 }


 public static void PromptCustomerPayment (Customer customer, Scanner sc) {

    // no more scanner instantiation
    ...
    // no more scanner close
 }

Hope this gives you some insight about the failure and possible resolution.

Problem

I'm new to using Java, but I have some previous experience with C#. The issue I'm having comes with reading user input from console. I'm running into the "java.util.NoSuchElementException" error with this portion of code: ``` payment = sc.next(); // PromptCustomerPayment function ``` I have two functions that get user input: - PromptCustomerQty - PromptCustomerPayment If I don't call PromptCustomerQty then I don't get this error, which leads me to believe I am doing something wrong with scanner. Below is my full code sample. I appreciate any help. ``` public static void main (String[] args) { // Create a customer // Future proofing the possabiltiies of multiple customers Customer customer = new Customer("Will"); // Create object for each Product // (Name,Code,Description,Price) // Initalize Qty at 0 Product Computer = new Product("Computer","PC1003","Basic Computer",399.99); Product Monitor = new Product("Monitor","MN1003","LCD Monitor",99.99); Product Printer = new Product("Printer","PR1003x","Inkjet Printer",54.23); // Define internal variables // ## DONT CHANGE ArrayList<Product> ProductList = new ArrayList<Product>(); // List to store Products String formatString = "%-15s %-10s %-20s %-10s %-10s %n"; // Default format for output // Add objects to list ProductList.add(Computer); ProductList.add(Monitor); ProductList.add(Printer); // Ask users for quantities PromptCustomerQty(customer, ProductList); // Ask user for payment method PromptCustomerPayment(customer); // Create the header PrintHeader(customer, formatString); // Create Body PrintBody(ProductList, formatString); } public static void PromptCustomerQty(Customer customer, ArrayList<Product> ProductList) { // Initiate a Scanner Scanner scan = new Scanner(System.in); // **** VARIABLES **** int qty = 0; // Greet Customer System.out.println("Hello " + customer.getName()); // Loop through each item and ask for qty desired for (Product p : ProductList) { do { // Ask user for qty System.out.println("How many would you like for product: " + p.name); System.out.print("> "); // Get input and set qty for the object qty = scan.nextInt(); } while (qty < 0); // Validation p.setQty(qty); // Set qty for object qty = 0; // Reset count } // Cleanup scan.close(); } public static void PromptCustomerPayment (Customer customer) { // Initiate Scanner Scanner sc = new Scanner(System.in); // Variables String payment = ""; // Prompt User do { System.out.println("Would you like to pay in full? [Yes/No]"); System.out.print("> "); payment = sc.next(); } while ((!payment.toLowerCase().equals("yes")) && (!payment.toLowerCase().equals("no"))); // Check/set result if (payment.toLowerCase().equals("yes")) { customer.setPaidInFull(true); } else { customer.setPaidInFull(false); } // Cleanup sc.close(); } ```

Original source