Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java.util.NoSuchElementException - Scanner reading user input

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();  } 
like image 789
fortune Avatar asked Oct 24 '12 02:10

fortune


People also ask

What is NoSuchElementException in Java scanner?

The NoSuchElementException is thrown by Scanner class, Iterator interface, Enumerator interface, and StringTokenizer class. These classes have accessors' methods to fetch the next element from an iterable. They throw NoSuchElementException if the iterable is empty or has reached the maximum limit.

How do I fix Java Util NoSuchElementException?

Solution. The solution to this​ exception is to check whether the next position of an iterable is filled or empty. You should only move to this position if the check returns that the position is not empty.

What does exception in thread main Java Util NoSuchElementException mean?

The NoSuchElementException in Java is thrown when one tries to access an iterable beyond its maximum limit. This means that, this exception is thrown by various accessor methods to indicate that the element being requested does not exist .

How does hasNextInt work in Java?

hasNextInt() method returns true if the next token in this scanner's input can be interpreted as an int value in the default radix using the nextInt() method. The scanner does not advance past any input.


Video Answer


1 Answers

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.

like image 59
Yogendra Singh Avatar answered Sep 28 '22 08:09

Yogendra Singh