JAVA - SCANNER获取用户输入

时间:2017-12-07 11:28:17

标签: java java.util.scanner

我有以下区块代码:

    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

有什么问题? 感谢

编辑:我认为我的问题在于&#34;做某事&#34;。它又是一系列用户输入,我关闭了扫描仪。

7 个答案:

答案 0 :(得分:2)

我取消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();
    }

答案 1 :(得分:1)

如果您调用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

答案 2 :(得分:1)

我认为你应该像这样更改一些代码行

        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();

答案 3 :(得分:1)

这是使用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

答案 4 :(得分:1)

问题实际上是在你的while循环条件下。我们来调试:

当您只输入与模式.last()不匹配的字符时,一切正常(用户将始终收到[YyNn]消息)。但是当你给出时,让我们说Incorrect input,你的while循环将停止,但Y将不被消耗。因此,此char将在下一条指令中使用,即在Y中(如果您打印变量String choice = scanner.next();,您将看到它有choice)。

在此之后,我们进入下一次迭代。由于没有要消费的输入,Y将为scanner.hasNext("[YyNn]")。但是你的while循环条件是false,它给我们一个!scanner.hasNext("[YyNn]")并进入循环内部。在循环内部,我们有指令true。由于没有要消耗的输入,BOOM,您得到java.util.NoSuchElementException,其中包含以下内容:

  

由枚举的nextElement方法抛出,表示枚举中没有更多元素。

您的其他问题在scanner.next()位置。在每次迭代中,您都在初始化一个新实例并将其关闭。您可以将扫描仪初始化及其闭包移到循环外。

下面我提供了一个类似的示例代码,可以通过一些解释来完成您想要的操作。

完整代码

scanner

希望它有所帮助!

答案 5 :(得分:1)

首先:您需要将扫描程序初始化行及其close()方法移出循环。

第二件事:在检查条件中添加fF,让你的程序退出循环,如果其中一个字母被输入Route::put('vehicletypes/{id}','API\VehicletypeController@putUpdate');

while (!scanner.hasNext("[YyNnFf]"))

答案 6 :(得分:1)

正如许多答案所暗示的那样,问题在于Scanner scanner = new Scanner(System.in);。以下是使用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;
        }
    }

你可以看到它正常工作here

注意:我已将模式匹配语句从[YyNn]更改为[YyNnFf] choice.toLowerCase().equals("f")更改为choice.toLowerCase().equalsIgnoreCase("f") ,因为这似乎是一个逻辑错误。看看它是否符合你的需要。