当前位置: 首页 > 面试题库 >

Java Scanner.nextLine()不等待输入

方波娃
2023-03-14
问题内容

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

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

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()问题。我将在下面发布整个课程的代码:

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因此不会抛出。相反,如前所述,将引发另一个异常,“
通常与找不到新行有关 ”- NoSuchElementException

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

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

由于引发了异常,因此将0返回的值,getUserChar然后将其用于run循环中:

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

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

若要更正此问题,请尝试使用一个Scanner并且不要关闭System.in;-)



 类似资料:
  • 在第一次迭代中,代码工作正常,我写了一些无效的东西(不是命令),代码打印警告并继续。但是其他迭代返回,如果(!scanin.hasnextline())返回null;,则返回

  • 我这里有两个代码块。一个扫描器正确地等待用户输入,另一个则直接通过它并调用,返回。下面是工作的块: 下面是没有的块: 这两个都是单独的类,并且是从另一个类中的main方法调用的。基本上,调用,后者又调用某个Player类的方法...这是非工作代码所在的地方。程序中是否有不适合接受输入的时候?我的印象是,任何时候我需要用户输入,我都可以使用这种方法。谢谢!

  • 问题内容: 我必须为计算机科学课做一个项目。问题是: 图书馆的顾客最多可以借三本书。因此,一个顾客有一个名字和最多三本书。一本书有作者和书名。设计并实现两个类,分别是Patron和Book,以表示这些对象和以下行为: 客户可以实例化带有标题和作者的书 客户可以检查但不能修改书名或作者 客户可以向顾客询问是否借用了给定的书(按书名识别)。 客户可以告诉顾客退还给定的书(按书名识别)。 客户可以告诉顾

  • 我正在尝试将数据库调用移出控制器,以清理并使其可测试。当它们在控制器中时,一切都会顺利进行。我将它们移出控制器,并添加了一个异步,以确保我们等待。否则,我将调用的中的函数。现在,一旦我使用async/await,控制器中的函数就会认为没有用户,因为它没有等待。 有几个关于异步等待的SO问题,但我没有找到一个解决我的问题。我确实验证了返回了我的用户,并添加了控制台日志来显示路径。 节点猫鼬异步等待似

  • 我正在编写一个棋盘游戏,我需要检查玩家正在移动的敌人并提示进行攻击。但是,由于游戏是如何制作的,移动方法是在JavaFX应用程序线程上调用的,我希望能够提示用户是否要与敌人战斗。 我的对话框工作正常,使用等待和通知,在主线程上不工作,会导致程序崩溃,有人知道如何暂停这个线程的执行,直到用户单击其中一个按钮。 我为描述道歉,太晚了。 检查敌人的方法该方法检查敌人,如果用户选择是,则返回敌人。它运行在

  • 问题内容: 我正在使用Java的扫描仪读取用户输入。如果我仅使用nextLine一次,那就可以了。使用两个nextLine时,第一个不会等待用户输入字符串(第二个会输入)。 输出: X:Y :(等待输入) 我的密码 任何想法为什么会发生这种情况?谢谢 问题答案: 您可能像以前那样调用方法。这样的程序是这样的: 演示您所看到的行为。 问题是不消耗,因此下一个调用将消耗它,然后等待读取的输入。 您需要