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

原文由 fortune 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 451
2 个回答

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

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

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

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

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

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

您的问题的唯一好的解决方案是在您的主要方法中启动 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
 }

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

原文由 Yogendra Singh 发布,翻译遵循 CC BY-SA 3.0 许可协议

问题是

当 Scanner 关闭时,如果源实现了 Closeable 接口,它将关闭其输入源。

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Scanner.html

因此 scan.close() 关闭 System.in

要修复它,你可以

Scanner scan static 不要在 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);
}

static Scanner scan;

public static void PromptCustomerQty(Customer customer, ArrayList<Product> ProductList)               {
// Initiate a 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

}

public static void PromptCustomerPayment (Customer customer) {
// Variables
String payment = "";

// Prompt User
do {
System.out.println("Would you like to pay in full? [Yes/No]");
System.out.print("> ");

payment = scan.next();

} while ((!payment.toLowerCase().equals("yes")) && (!payment.toLowerCase().equals("no")));

// Check/set result
if (payment.toLowerCase() == "yes") {
    customer.setPaidInFull(true);
}
else {
    customer.setPaidInFull(false);
}
}

另外,您不应该使用 == 进行字符串比较,而是使用 .equals

原文由 user1766873 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题