java.util.NoSuchElementException - 扫描仪读取用户输入

标签 java input java.util.scanner nosuchelementexception

我刚开始使用 Java,但之前有一些使用 C# 的经验。我遇到的问题是从控制台读取用户输入。

我在这部分代码中遇到了“java.util.NoSuchElementException”错误:

payment = sc.next(); // PromptCustomerPayment function

我有两个获取用户输入的函数:

  • 提示客户数量
  • 提示客户付款

如果我不调用 PromptCustomerQty,那么我就不会收到此错误,这使我相信我的扫描仪出了问题。下面是我的完整代码示例。我感谢任何帮助。

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

最佳答案

这确实让我困惑了一段时间,但这是我最终发现的。

当您在第一个方法中调用 sc.close() 时,它不仅会关闭您的扫描仪,还会关闭您的 System.in 输入流。您可以通过在第二个方法的最顶部打印其状态来验证它,如下所示:

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

因此,现在当您在第二种方法中重新实例化 Scanner 时,它找不到任何打开的 System.in 流,因此出现异常。

我怀疑是否有办法重新打开System.in,因为:

public void close() throws IOException --> 关闭此输入流并释放与此流关联的所有系统资源。 close 的一般约定是关闭输入流。关闭的流无法执行输入操作,并且**无法重新打开。**

解决您的问题的唯一好的解决方案是在您的主方法中启动 Scanner,将其作为参数传递到您的两个方法中,然后在您的主方法中再次关闭它,例如:

main方法相关代码块:

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

你的方法:

 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
 }

希望这能让您对失败和可能的解决方案有一些了解。

关于java.util.NoSuchElementException - 扫描仪读取用户输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42707904/

相关文章:

java - 对象化查询不适用于祖先

java - 在哪里可以找到 Java JMF 教程

java - Java SE 中的事务类型

java - 扫描仪长度不匹配! java

java - 在方法中实现计时器

java - 如何使用 find() 而不改变 Matcher 的状态?

vue.js - Vue - 将默认值设置为输入文本

javascript - 减少javascript中的输入数量

c - 为什么C中的字符串数组开头存放的是一个空元素?

Java - 如何仅接受日期输入的整数?