如何处理 java 中的空扫描器输入字符串?

How to handle empty scanner input strings in java?

我正在开发 .xml 文件生成器。它的工作原理是要求用户输入 5 个不同的值,然后使用它们生成一个 .xml 数据容器。这是代码:

public class Generator {
public static void main(String[] args) throws InterruptedException {
    Scanner reader = new Scanner(System.in);
    while (true) {

        System.out.println("Input the furni ID (input only numbers here).");
        String furniID = reader.nextLine();

        System.out.println("Input the furni's file name (without '.swf'. You can input numbers, letters and underscores here).");
        String furniFileName = reader.nextLine();

        System.out.println("Input the furni's revision (input only numbers here).");
        String furniRevision = reader.nextLine();

        System.out.println("Input the furni's name (this will be the name that it will display when you click on the furni in a room or in your inventory).");
        String furniName = reader.nextLine();

        System.out.println("Input the furni's description (this will be displayed under the furni's name).");
        String furniDescription = reader.nextLine();

        System.out.println("Input the furni's furniline. This is just a name for a group of furnis that belong to the same collection. For example you can input 'custom' (without quotation marks).");
        String furniLine = reader.nextLine();

        System.out.println("Generating your furnidata...");
        System.out.println(" ");

        TimeUnit.SECONDS.sleep(1);

        System.out.println("<furnitype id=\"" + furniID + "\"" + " classname=\"" + furniFileName + "\"" + ">");
        System.out.println("<revision>" + furniRevision + "</revision>");
        System.out.println("<xdim>1</xdim>");
        System.out.println("<ydim>1</ydim>");
        System.out.println("</partcolors>");
        System.out.println("<name>" + furniName + "</name>");
        System.out.println("<description>" + furniDescription + "</description>");
        System.out.println("</adurl");
        System.out.println("<offerid>-1</offerid>");
        System.out.println("<buyout>0</buyout>");
        System.out.println("<rentofferid>-1</rentofferid>");
        System.out.println("<rentbuyout>0</rentbuyout>");
        System.out.println("<bc>0</bc>");
        System.out.println("<excludeddynamic>0</excludeddynamic>");
        System.out.println("<customparams/>");
        System.out.println("<specialtype>1</specialtype>");
        System.out.println("<canstandon>0</canstandon>");
        System.out.println("<cansiton>0</cansiton>");
        System.out.println("<canlayon>0</canlayon>");
        System.out.println("<furniline>" + furniLine + "</furniline>");
        System.out.println("</furnitype>");
        System.out.println(" ");

        System.out.println("Do you want to generate another furnidata? (YES/NO)");
        String confirmation = reader.nextLine();

        if (confirmation.equals("NO")) {
            System.out.println("Furnidata generator has been stopped.");
            break;
        } else if (confirmation.equals("no")) {
            System.out.println("Furnidata generator has been stopped.");
            break;
        } else if (confirmation.equals("No")) {
            System.out.println("Furnidata generator has been stopped.");
            break;
        }
    }
}

我希望程序能够检测到有人在没有写入文本的情况下通过按下回车键输入空字符串,并打印一条消息,要求用户不要输入空字符串。我用 try-catch 语句尝试了这个,但在打印消息后,程序执行下一行,而不是重新执行用户输入空字符串的那一行。我怎样才能做到这一点?

您可能想要使用。

 String furniID = reader.nextLine();
 furniID = furniID.trim();
 if(furniID.equals("")){
     System.out.println("Empty Here. ");
 }

如评论中所建议 .readLine() returns 如果您提供空白行或直接按回车键,则为空字符串。

以上正则表达式将处理用户可能输入的空字符串 ""whitespaces

编辑 1 正如评论中所建议的那样,正则表达式可能在这里被过度杀戮。 string.trim() 将处理制表符、尾随前导空格和空字符串。

每当提示用户提供特定数据时,您应该验证输入的数据,如果不正确,允许用户重试,以免由于某些错误而停止应用程序可以避免的那种。 没问题使用Regular Expressions(正则表达式)来处理这类事情。

用户什么都不输入(只需按 ENTER 键)只是一个问题。在某些提示下,您希望用户仅输入数字。 String#matches() 方法中的一个小正则表达式非常适合这个,例如:

if (!userInput.matches("\d+") {
   System.out.println("Invalid input! Numerical digits only!");
}

如果用户输入匹配所有数字,则显示“输入无效!”。

每个提示都应在其自己的 dowhile 循环中,以便可以进行验证并为用户提供重新输入数据的机会。如果您有很多提示,那么可以创建一个 class 方法来处理所有提示,以消除重复编码。例如,这里修改了您的代码,以便名为 askUser() 的方法可以处理对用户的提示:

public class Generator {

    public static void main(String[] args) {
        java.util.Scanner reader = new java.util.Scanner(System.in);
        while (true) {
            // Only a String repesentation of numerical digits will be accepted. 
            // 1 to 20 digits are acceptable)
            String furniID = askUser(reader, "Input the furni ID (input only numbers here).", 
                    "\d{1,20}");

            /* Only characters A to Z in either upper or lower case, digits 
               from 0 to 9, whitespaces, and underscores will be accepted 
               within the Users input. The period (.) is not acceptable 
               therefore eliminating the possibility of a file name extension
               like .swf to be applied to the supplied file name. File name can 
               be 1 to 80 characters.                               */
            String furniFileName = askUser(reader, "Input the furni's file name (without "
                    + "'.swf'.\nYou can input numbers, letters and underscores here).", 
                    "(?i)[a-z0-9 _]{1,80}");
            
            // Only a String repesentation of numerical digits will be accepted. 
            // 1 to 20 digits are acceptable)
            String furniRevision = askUser(reader, "Input the furni's revision (input "
                    + "only numbers here).", "\d{1,20}");
            
            /* Only characters A to Z in either upper or lower case, digits 
               from 0 to 9, whitespaces, and underscores will be accepted 
               within the Users input. The period (.) is not acceptable. The
               name can be 1 to 25 characters in length.                  */
            String furniName = askUser(reader, "Input the furni's name (this will be "
                    + "the name that will\nbe displayed when you click on the furni in "
                    + "a room or in\nyour inventory).", "(?i)[a-z0-9 _]{1,25}");

            /* Only characters A to Z in either upper or lower case, digits 
               from 0 to 9, whitespaces, and periods will be accepted within 
               the Users input. Description can be a minimum of 5 to a maximum 
               of 120 characters in length.  */
            String furniDescription = askUser(reader, "Input the furni's description ("
                    + "this will be displayed\nunder the furni's name).", "(?i)[a-z0-9. ]{5,120}");

            /* Only characters A to Z in either upper or lower case, digits 
               from 0 to 9, and whitespaces will be accepted within the Users 
               input. The period (.) is not acceptable. The furniline name can 
               be 1 to 25 characters in length.                      */   
            String furniLine = askUser(reader, "Input the furni's furniline. This is just "
                    + "a name for a\ngroup of furnis that belong to the same collection. "
                    + "For\nexample you can input 'custom' (without quotation marks).", 
                    "(?i)[a-z0-9 ]{1,25}");

            System.out.println("Generating your furnidata...");
            System.out.println(" ");
            System.out.println("<furnitype id=\"" + furniID + "\"" + " classname=\"" + furniFileName + "\"" + ">");
            System.out.println("<revision>" + furniRevision + "</revision>");
            System.out.println("<xdim>1</xdim>");
            System.out.println("<ydim>1</ydim>");
            System.out.println("</partcolors>");
            System.out.println("<name>" + furniName + "</name>");
            System.out.println("<description>" + furniDescription + "</description>");
            System.out.println("</adurl");
            System.out.println("<offerid>-1</offerid>");
            System.out.println("<buyout>0</buyout>");
            System.out.println("<rentofferid>-1</rentofferid>");
            System.out.println("<rentbuyout>0</rentbuyout>");
            System.out.println("<bc>0</bc>");
            System.out.println("<excludeddynamic>0</excludeddynamic>");
            System.out.println("<customparams/>");
            System.out.println("<specialtype>1</specialtype>");
            System.out.println("<canstandon>0</canstandon>");
            System.out.println("<cansiton>0</cansiton>");
            System.out.println("<canlayon>0</canlayon>");
            System.out.println("<furniline>" + furniLine + "</furniline>");
            System.out.println("</furnitype>");
            System.out.println(" ");

            // Only y or n can be supplied in any letter case. 
            // Anything else generates an Invalid Input message.
            String confirmation = askUser(reader, "Do you want to generate another furnidata? (y/n)", 
                    "(?i)[yn]", "Invalid Choice! Either 'y' for Yes or 'n' for No!");
            if (confirmation.equalsIgnoreCase("n")) {
                System.out.println("Furnidata generator has been stopped.");
                break;
            }
        }
    }
    
    /**
     * Displays the supplied prompt within the Console Window and permits the User 
     * to enter a response. User input is validated based on the regex argument 
     * supplied to the <b>validationRegEx</b> parameter.<br><br>
     * 
     * @param inputReader (Scanner) Scanner object to use for User Input.<br>
     * 
     * @param promptString (String) The prompt to display within the console window.<br>
     * 
     * @param validationRegEx (String) A regular expression that will be used 
     * within a <b>String#matches()</b> method to validate the User's input.<br>
     * 
     * @param errorString (Optional - String) Default validation error message is:<pre>
     * 
     *     "Invalid input! Try again..."</pre><br>
     * 
     * Here you can optionally supply your own message for non-valid entries.<br>
     * 
     * @return (String) The valid response from User.
     */
    public static String askUser(java.util.Scanner inputReader, String promptString, String validationRegEx, String... errorString) {
        String userInput = "";
        String errString = "Invalid input! Try again...";
        if (errorString.length > 0 && !errorString[0].trim().isEmpty()) {
            errString = errorString[0];
        }
        
        while (userInput.isEmpty()) {
            System.out.println();
            System.out.println(promptString);
            userInput = inputReader.nextLine();
            if (!userInput.matches(validationRegEx)) {
                System.err.println(errString);
                userInput = "";
            }
        }
        return userInput;
    }
    
}