简体   繁体   English

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

[英]How to handle empty scanner input strings in java?

I'm working on a .xml file generator.我正在研究 .xml 文件生成器。 It works by asking the user to input 5 different values and then using them for generating a .xml data container.它的工作原理是要求用户输入 5 个不同的值,然后使用它们生成一个 .xml 数据容器。 This is the code:这是代码:

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;
        }
    }
}

I want the program to detect when someone inputs an empty string by pressing the enter key with no written text and print a message asking the user to not input empty strings.我希望程序检测何时有人通过按下没有文字的回车键输入空字符串并打印一条消息,要求用户不要输入空字符串。 I tried this with a try-catch statement but after printing the message the program executes the next line instead of re-executing the one where the user input an empty string.我用 try-catch 语句尝试过这个,但在打印消息后,程序执行下一行,而不是重新执行用户输入空字符串的那一行。 How can I achieve this?我怎样才能做到这一点?

Whenever you have a prompt for a User to supply specific data you should validate that data that was entered and if it is incorrect, permit the User to try again so as not to halt the application due to an error of some kind that can be avoided.每当您提示用户提供特定数据时,您应该验证输入的数据,如果不正确,请允许用户重试,以免由于某种可以避免的错误而停止应用程序. There is no problem using Regular Expressions (regex) for this sort of thing.对这类事情使用正则表达式(regex)没有问题

A User entering nothing (by just hitting the ENTER key) is just one problem.用户不输入任何内容(只需按ENTER键)只是一个问题。 At some prompts you are expecting the User to enter only numerical digits.在某些提示下,您希望用户仅输入数字。 A small regex within the String#matches() method is ideal for this, for example: String#matches()方法中的一个小的正则表达式非常适合于此,例如:

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

If the User input does not match all numerical digits then display "Invalid Input!".如果用户输入与所有数字匹配,则显示“无效输入!”。

Every prompt should be in its own do or while loop so that validation can be done and an opportunity for the User to re-enter the data can be accomplished.每个提示都应该在它自己的dowhile循环中,以便可以完成验证并为用户提供重新输入数据的机会。 If you have lots of prompts then a class method can be created to handle all of them in order to remove duplicate coding.如果您有很多提示,那么可以创建一个类方法来处理所有提示,以删除重复的编码。 As an example, here is your code modified so that a method named askUser() can handle the prompts to the User:例如,这里修改了您的代码,以便名为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;
    }
    
}

You might want to use.您可能想要使用。

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

As suggested in comments .readLine() returns an empty string if you supply a blankline or simply hit enter.正如评论中所建议的,如果您提供一个空白行或直接按 Enter 键,则.readLine()将返回一个空字符串。

The above regex expression will take care of empty string "" or whitespaces that user might enter.上面的正则表达式将处理用户可能输入的空字符串""whitespaces

edit 1 As suggested in comments regex could have been over-kill here.编辑 1正如评论中所建议的那样,正则表达式在这里可能会过度使用。 The string.trim() will take care of tabs, trailing-leading whitespaces and empty string. string.trim()将处理制表符、尾随空格和空字符串。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM