Java Scanner.nextLine()不等待输入

我有几个方法,我以前用来接受用户输入并将其作为特定数据类型返回到调用它的方法。 我在以前的项目中使用过这些方法或它们的变体。

我已经采用了我用于字符串的方法来选择给定的第一个字符并返回它,以便我可以在菜单中使用它。 每次启动应用程序时,都会出现主菜单并等待用户输入。 收到此输入后,程序会一直循环直到停止。 这是我捕获char的方法:

private char getUserChar(String prompt) { try { Scanner scan = new Scanner(System.in); System.out.print(prompt); String tempString = ""; tempString = scan.nextLine(); scan.close(); char userChar = tempString.charAt(0); return userChar; } catch(Exception ex) { System.out.println(ex.getMessage()); } return 0; } 

由于try / catch块,代码循环,因为scan.nextLine()从不等待下一个输入。 没有它,例外通常与找不到新行有关。 我尝试了似乎适合其他人的while(scan.hasNextLine()); 但是,一旦输入的时间到来,它就永远不会脱离循环。 我也不相信我正在绊倒每个人似乎都遇到麻烦的nextInt()问题。 我将在下面发布整个class级的代码:

 import java.util.Scanner; import controller.Controller; public class TUI { private Controller controller; public TUI() { Controller controller = new Controller(); this.controller = controller; } public void run() { boolean wantToQuit = false; char userInput = 0; System.out.println("Welcome to the Mart."); do{ userInput = mainMenu(); if(isUserInputValid(userInput)) switch(userInput){ case 'a': addItem(); break; case 'r': controller.removeItem(); break; case 'i': controller.printInventory(); break; case 'p': controller.customerPurchase(); break; case 'w': controller.weeklyStock(); break; case 'c': wantToQuit = true; break; } else System.out.println("\nMainMenu"); } while(!(wantToQuit)); System.out.println("WolfMart is now closed. Thank you and good-bye."); } private boolean isUserInputValid(char userInput) { char[] testSet = {'a', 'r', 'i', 'p', 'c', 'w'}; for(char currentChar : testSet) { if(currentChar == userInput) return true; } return false; } private char mainMenu() { System.out.println(); controller.printInventory(); String mainMenuSelection = "What would you like to do: (a)dd item, (r)emove item, print (i)nventory, " + "(p)urchase by customer, (c)lose store?\r\n"; char mainMenuInput = getUserChar(mainMenuSelection); return mainMenuInput; } private char getUserChar(String prompt) { try { Scanner scan = new Scanner(System.in); System.out.print(prompt); String tempString = ""; tempString = scan.nextLine(); scan.close(); char userChar = tempString.charAt(0); return userChar; } catch(Exception ex) { System.out.println(ex.getMessage()); } return 0; } private int getUserInt(String prompt) { Scanner scan = new Scanner(System.in); int userInt = -1; try { System.out.print(prompt); String input = scan.nextLine(); userInt = Integer.parseInt(input); } catch(NumberFormatException nfe) { System.out.println("I did not recognize your command, please try again."); } scan.close(); return userInt; } private String getUserString(String prompt) { Scanner scan = new Scanner(System.in); String userString = null; try{ System.out.print(prompt); userString = scan.nextLine(); } catch(Exception ex) { System.out.println("I did not recognize your command, please try again."); } scan.close(); return userString; } private double getUserDouble(String prompt) { Scanner scan = new Scanner(System.in); double userDouble = -1.0; try { System.out.print(prompt); String input = scan.nextLine(); userDouble = Double.parseDouble(input); } catch(NumberFormatException nfe) { System.out.println("I did not recognize your command, please try again."); } scan.close(); return userDouble; } private void addItem() { String itemName = ""; double price; int quantity; String namePrompt = "Enter the name of the item being added to the inventory: "; String pricePrompt = "Enter the cost of " + itemName + ": "; String quantityPrompt = "Enter the quantity of " + itemName + ": "; itemName = getUserString(namePrompt); price = getUserDouble(pricePrompt); quantity = getUserInt(quantityPrompt); controller.addItem(itemName, quantity, price); } } 

正如我在评论中所说,问题是你每次做这样的事情时都要关闭System.in

 Scanner scan = new Scanner(System.in); ... scan.close(); 

现在,看看Scanner.nextLine的规范

抛出

  • NoSuchElementException – 如果未找到任何行
  • IllegalStateException – 如果此扫描程序已关闭

现在,由于扫描程序本身未关闭,因此不会抛出IllegalStateException 。 相反,正如您之前提到的,抛出了另一个exception,“ 通常与找不到新行有关 ”, – NoSuchElementException

假设您正在使用JDK 7,您可以通过检查Scanner.throwFor来了解其工作原理:

 if ((sourceClosed) && (position == buf.limit())) throw new NoSuchElementException(); 

抛出exception后, getUserChar返回值0 ,然后在run循环中使用:

 do{ userInput = mainMenu(); if(isUserInputValid(userInput)) ... else System.out.println("\nMainMenu"); } while(!(wantToQuit)); 

由于输入无效,您将陷入循环打印"\nMainMenu\n"

要解决此问题,请尝试使用单个Scanner ,不要关闭System.in 😉

不要关闭 Scanner

 scan.close(); // Don't do it. 

这样做会导致问题。