![](/img/trans.png)
[英]Java - combine Scanner for file with Scanner for user input
[英]JAVA - SCANNER to get user input
我有以下代碼:
boolean run = true;
while (run) {
Scanner scanner = new Scanner(System.in);
// do something
System.out.println("Another action? [Y/N]");
while (!scanner.hasNext("[YyNn]")) {
System.out.println("Incorrect input");
scanner.next();
}
String choice = scanner.next();
if (choice.toLowerCase().equals("f"))
run = false;
scanner.close();
}
在用戶鍵入“ N”之前,我想執行一些操作。 目前,我只能運行一次while循環。 第二次我無法鍵入選擇,並且出現以下錯誤:
Another action? [Y/N] <--- here no chance to type choice
Incorrect input
java.util.NoSuchElementException
at java.util.Scanner.throwFor
at java.util.Scanner.next
怎么了? 謝謝
編輯:我認為我的問題是在“做某事”。 這又是我關閉掃描儀的一系列用戶輸入。
我摘下了scanner.close();
並在模式中添加"fF"
,直到我輸入f或F:
boolean run = true;
while(run){
System.out.println("Another action? [Y/N]");
while (!scanner.hasNext("[YyNnfF]")) {
System.out.println("Incorrehct input");
scanner.next();
}
String choice = scanner.next();
if(choice.toLowerCase().equals("f"))
run = false;
// scanner.close();
}
如果調用scanner.close()方法,System.in將關閉。 所以用這個。 在回路外關閉掃描儀。
public static void main(String[] args) {
boolean run = true;
Scanner scanner = new Scanner(System.in);;
while(run){
// do something
System.out.println("Another action? [Y/N]");
while (!scanner.hasNext("[YyNn]")) {
System.out.println("Incorrect input");
scanner.next();
}
String choice = scanner.next();
if(choice.toLowerCase().equals("f"))
run = false;
//
}
scanner.close();
}
輸出量
Another action? [Y/N]
Y
Another action? [Y/N]
Y
Another action? [Y/N]
N
Another action? [Y/N]
N
Another action? [Y/N]
test
Incorrect input
我認為您應該像這樣更改一些代碼行
Scanner scanner = new Scanner(System.in);
char choice = 'Y'
while(choice!='n'){
// do something
System.out.print("Another action? [Y/N]");
choice = scanner.nextLine().toLowerCase().charAt(0);
if(choice!='y' || choice!='n'){
continue;
}
}
scanner.close();
這是使用Java8的正確版本
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ScannerExample {
public static void main(String[] args) {
boolean run = true;
try (Scanner sc = new Scanner(System.in)) {
while (run) {
System.out.println("Another action? [Y/N]");
String option = sc.next();
Pattern patter = Pattern.compile("[YyNn]");
Matcher m = patter.matcher(option);
while (!m.matches()) {
System.out.println("Incorrect input");
option = sc.next();
m = patter.matcher(option);
}
option = sc.next();
if (option.toLowerCase().equals("f")) {
run = false;
}
}
} catch (Exception e) {
// TODO: handle exception
}
}
}
輸出:
Another action? [Y/N]
Y
N
Another action? [Y/N]
Y
N
Another action? [Y/N]
f
Incorrect input
Y
N
Another action? [Y/N]
f
Incorrect input
Y
f
問題實際上出在您的while循環條件中。 讓我們調試一下:
當您僅輸入與模式[YyNn]
不匹配的字符時,一切正常(用戶將始終收到Incorrect input
消息)。 但是,當您給出一個Y
,您的while循環將停止,但不會消耗Y
因此,此字符將在下一條指令中使用,即在String choice = scanner.next();
(如果您打印變量choice
您將看到它具有Y
)。
此后,我們轉到下一個迭代。 因為沒有輸入要消耗, scanner.hasNext("[YyNn]")
將為false
。 但是您的while循環條件是!scanner.hasNext("[YyNn]")
,這使我們成為true
並進入了循環。 在循環內部,我們有指令scanner.next()
。 由於沒有要使用的輸入BOOM,因此您將獲得一個java.util.NoSuchElementException ,它表示以下內容:
由Enumeration的nextElement方法拋出,以指示該枚舉中沒有更多元素。
您的其他問題出在scanner
位置。 在每次迭代中,您都要初始化一個新實例並關閉它。 您可以將掃描器的初始化及其關閉移動到循環之外。
下面,我提供了一個類似的示例代碼,其中包含一些說明,可以滿足您的要求。
完整代碼
public static void main(String[] args) {
boolean run = true;
Scanner scanner = new Scanner(System.in); // Init before loops
String userInput = ""; // tmp var that holds input
while (run) {
// do something
System.out.println("Another action? [Y/N]");
userInput = scanner.next(); // Read first time
// Run while user does not put Y || y || N || n
while (!userInput.matches("[YyNn]")){
System.out.println("Incorrect input");
userInput = scanner.next();
}
// User does not want more actions
if(userInput.matches("[Nn]")){
System.out.println("Do you wish to exit the program? [Y/Any other key]");
String choice = scanner.next();
// Stop the program
if (choice.toLowerCase().equals("y"))
run = false;
}
}
scanner.close(); // Close scanner outside
}
希望能有所幫助!
第一件事:您需要將掃描器初始化行及其close()方法都移到循環外。
第二件事:在檢查條件中添加fF,如果while (!scanner.hasNext("[YyNnFf]"))
中鍵入以下字母之一時,讓您的程序退出循環。
public static void main(String[] args) {
boolean run = true;
Scanner scanner = new Scanner(System.in);
while (run) {
// do something
System.out.println("Another action? [Y/N]");
while (!scanner.hasNext("[YyNnFf]")) {
System.out.println("Incorrect input");
scanner.next();
}
String choice = scanner.next();
if (choice.toLowerCase().equals("f")) {
run = false;
}
}
scanner.close();
}
正如許多答案所暗示的那樣,問題出在“ Scanner scanner = new Scanner(System.in);
。 以下是使用try-with-resources
的更正版本, try-with-resources
是一種使用Java處理資源的更干凈的方法:
boolean run = true;
try(Scanner scanner = new Scanner(System.in))
{
while (run)
{
System.out.println("Another action? [Y/N]");
while (!scanner.hasNext("[YyNnFf]")) {
System.out.println("Incorrect input");
scanner.next();
}
String choice = scanner.next();
if (choice.toLowerCase().equalsIgnoreCase("f"))
run = false;
}
}
您可以看到它在這里工作。
注意:我已將模式匹配語句從[YyNn]
更改為[YyNnFf]
並將 choice.toLowerCase().equals("f")
更改為choice.toLowerCase().equalsIgnoreCase("f")
,因為這似乎是邏輯錯誤。 看看是否根據您的需要。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.