java.util.NoSuchElementException - 扫描器读取用户输入
我是使用 Java 的新手,但我以前使用过 C#.我遇到的问题是从控制台读取用户输入.
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.
我遇到了java.util.NoSuchElementException".这部分代码出错:
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,则不会收到此错误,这使我相信我在扫描仪上做错了.下面是我的完整代码示例.感谢您的帮助.
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();
}
推荐答案
这确实让我困惑了一段时间,但这是我最终找到的.
当您在第一种方法中调用 sc.close()
时,它不仅会关闭您的扫描仪,还会关闭您的 System.in
输入流.您可以通过在第二种方法的最顶部打印其状态来验证它:
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());
所以,现在当您在第二种方法中重新实例化 Scanner
时,它不会找到任何打开的 System.in
流,因此会出现异常.
So, now when you re-instantiate, Scanner
in second method, it doesn't find any open System.in
stream and hence the exception.
我怀疑是否有办法重新打开 System.in
因为:
I doubt if there is any way out to reopen System.in
because:
public void close() throws IOException -->关闭此输入流并释放与此流关联的所有系统资源.close 的一般约定是它关闭输入流.关闭的流无法执行输入操作,并且**无法重新打开.**
解决您的问题的唯一好方法是在您的 main 方法中启动 Scanner
,将其作为参数传递给您的两个方法,然后在您的 main 方法中再次关闭它,例如:
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
方法相关代码块:
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
}
希望这能让您对失败和可能的解决方案有所了解.
Hope this gives you some insight about the failure and possible resolution.
相关文章