簡體   English   中英

JAVA-SCANNER獲取用戶輸入

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM