我刚开始使用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();
}
5条答案
按热度按时间cqoc49vn1#
这确实让我困惑了一段时间,但这是我最终的发现。
当你在第一个方法中调用
sc.close()
时,它不仅关闭了你的扫描仪,也关闭了你的System.in
输入流。你可以通过在第二个方法的最顶端打印它的状态来验证它:所以,现在当你在第二个方法中重新示例化
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.**
解决这个问题的唯一好办法是在main方法中初始化
Scanner
,在两个方法中将其作为参数传递,然后在main方法中再次关闭它,例如:main
方法相关代码块:您的方法:
希望这能帮助您了解故障和可能的解决方案。
roejwanj2#
问题是
当扫描器关闭时,如果输入源实现Closeable接口,则扫描器将关闭该输入源。
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Scanner.html
因此
scan.close()
闭合System.in
。要修复它,您可以
Scanner scan
static
并且在PromptCustomerQty中不关闭。下面的代码可以工作。另外,不应该使用
==
进行字符串比较,而应该使用.equals
。wecizke33#
您需要删除扫描仪关闭行:
scan.close();
我以前也遇到过,这就是原因。
sf6xfgos4#
例外的原因已经解释过了,但是建议的解决方案实际上并不是最好的。
您应该创建一个类,使用Singleton模式将Scanner保持为私有的,这使得该扫描器在您的代码中是唯一的。
然后,您可以实现所需的方法,或者创建一个getScanner(不推荐),并使用私有布尔值(如alreadyClosed)来控制它。
如果你不知道如何使用Singleton模式,这里有一个例子:
ktecyv1j5#
对于任何在HackerRank这样的网站上参加在线考试的人来说-
如果您试图通过单击按钮以使用自定义输入执行main()来测试(可能)完美的代码,则可能会收到此消息。
在这种情况下,你需要点击另一个按钮,比如“运行单元测试”。你可能只会被评估代码是否通过了他们编写的单元测试,而不是你重构代码以减少LOC的能力或你的编码风格。