带有JOptionPane的循环返回StringIndexOutOfBounds异常

问题描述 投票:0回答:1

在我的代码中,我有一个while循环,其中嵌套了3个IF测试,这些测试具有由ELSE触发的标志:

[test1]检查输入值的长度是否正好为1 [防止用户不输入任何内容]

[test2]检查索引0处的输入值是否为数字[我需要一个数字作为输入,但是我正在使用JSWING]

[test3]检查输入值的长度是否大于1 [2位数字(10,11,12,...)

 num1= JOptionPane.showInputDialog(null,"Please input Guess #" + (counter+1), "0"); 
                 while(exit == false || test1 == false || test2 == false || test3 == false) {
                     if(num1.length() < 1) {
                         JOptionPane.showMessageDialog(null,"Input required");
                         num1= JOptionPane.showInputDialog(null,"Please input Guess #" + (counter+1), "0");
                     }
                     else {
                         test1 = true;
                     }
                     if(Character.isDigit(num1.charAt(0)) == false) {
                         JOptionPane.showMessageDialog(null,"Input has to be a number between 0 - 9.");
                         num1= JOptionPane.showInputDialog(null,"Please input Guess #" + (counter+1), "0");
                     }
                     else {
                         test2 = true;
                     }
                     if(num1.length() > 1) {
                         JOptionPane.showMessageDialog(null,"Input has to be a number between 0 - 9.");
                         num1= JOptionPane.showInputDialog(null,"Please input Guess #" + (counter+1), "0");
                     }
                     else {
                         test3 = true;
                     }
                     if(test1 == true && test2 == true && test3 == true) {
                         exit = true;
                     }

我遇到的问题在第一次测试和第二次测试之间。当我尝试不输入任何内容作为值[“” /或仅具有一个空框并按Enter]时,它检测到没有任何内容的错误,并一次显示“ Input required”,但一旦循环,则第二次输出StringIndexOutOfBoundsException试用它在我尝试过的所有其他情况下都有效(无输入->正确,无输入->不正确...)只有顺序无输入的情况会使程序崩溃。

据说此行中有错误,但我不知道在哪里或如何。

if(Character.isDigit(num1.charAt(0)) == false)

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 0
at java.base/java.lang.StringLatin1.charAt(StringLatin1.java:48)
at java.base/java.lang.String.charAt(String.java:709)
at oof.Lottery_Swing_FIX.main(Lottery_Swing_FIX.java:56)

固定逻辑

                JOptionPane.showMessageDialog(null,"Enter 3 one-digit positive numbers for your 3 guesses");
             for(int counter = 0; counter < LIMIT; counter++) {
                 test = false; 

                 while(exit == false || test == false) {
                     num1= JOptionPane.showInputDialog(null,"Please input Guess #" + (counter+1), ""); 
                     if(num1.length() < 1 || Character.isDigit(num1.charAt(0)) == false || num1.length() > 1) {
                         JOptionPane.showMessageDialog(null,"Integer between 1-9 required");
                     }
                     else {
                         test = true;
                     }
                     if(test == true) {
                         numberInput = Integer.parseInt(num1);
                         exit = true;
                     }
                     else {
                         continue;
                     }
                 }
java if-statement indexoutofboundsexception charat
1个回答
0
投票

您的'修复'不处理null,如果对话框关闭(x)或取消取消],则JOptionPane.showInputDialog()将返回该null按钮被选择。您不能像使用Null String“”)对String#length()方法播放null一样,所以,则需要在代码中进行检查,否则最终可能会出现NullPointerException。您可以在第一个

if语句中作为条件组件来执行此操作:

if (num1 == null) { // The CANCEL or dialog close button was selected. }

您确实不需要在代码中使用这些布尔标志。事情将会发生,或者根本不会发生。您真的不需要标志来提醒您离家这么近(可以这么说)。如果您在if语句中正确建立了条件并利用else if,则不需要这些条件。话虽这么说,您也不需要在[[while循环的条件内使用这些布尔标志。

while循环需要关注一件事...提示已提供有效数据。如果不是,则保存提示数据的变量(num1)将转换为空字符串(“”)。所以实际上:

String num1 = "";
while (num1.equals("")) { .... }

因此,只要num1包含空字符串(“”),我们就保持循环,从而重新提示正确的输入。

在您的代码中,您想向用户提供有关输入失败原因的特定详细信息。有多种方法可以执行此操作,但是无论选择哪种方法,请确保它不会生成任何最终导致应用程序停止运行或更改其准确性能的异常(错误)。使用ifelse if语句在当前用例中执行此特定任务没有任何问题。按照您的特定主题:

int LIMIT = 3, numberInput;
int[] guesses = new int[LIMIT];
String errMsg;
String num1;
JOptionPane.showMessageDialog(null, "<html>You will be prompted three times "
           + "to supply<br>a positive <font color=red><b>single digit</b></font> "
           + "number.</html>", "Information", JOptionPane.INFORMATION_MESSAGE);
for (int counter = 0; counter < LIMIT; counter++) {
    num1 = "";
    while (num1.equals("")) {
        errMsg = "";
        num1 = JOptionPane.showInputDialog(null, "Please input Guess #" + (counter + 1), 
                                           "Guess #" + (counter + 1),JOptionPane.QUESTION_MESSAGE);
        // Does num1 contain null?
        if (num1 == null) {
            if (JOptionPane.showConfirmDialog(null,
                    "<html>You <font color=blue>canceled</font> your input!<br>"
                    + "Do you want to quit?</html>", "Quit",
                    JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
                System.exit(0);
            }
            num1 = ""; // Set for re-prompt.
            continue;
        }
        // Is nothing supplied?
        else if (num1.length() < 1) {
            errMsg = "<html><font size=5 color=red><center>Nothing Supplied!"
                     + "</center></font><br>You must provide a single Integer "
                     + "value between<br>0 and 9 (inclusive).</html>";
        }
        // Is too much supplied?
        else if (num1.length() > 1) {
            errMsg = "<html><center><font size=5 color=red>To Much Supplied!</font><br>" +
                     "<font size=5 color=blue>\"" + num1 + "\"</font></center><br>" +
                     "You must provide a single Integer value between<br>0 and 9 "
                     + "(inclusive).</html>";

        }
        // Is the supplied character a number?
        else if (!Character.isDigit(num1.charAt(0))) {
            errMsg = "<html><center><font size=5 color=red>Invalid Digit Supplied!"
                     + "</font><br><font size=5 color=blue>\"" + num1 + "\"</font>"
                     + "</center><br>You must provide a single Integer value "
                     + "between<br>0 and 9 (inclusive).</html>";
        }

        // Does errMsg actually contain a message? If so display it.
        if (!errMsg.equals("")) {
            JOptionPane.showMessageDialog(null, errMsg, "Invalid Input!", 
                                          JOptionPane.WARNING_MESSAGE);
            num1 = ""; // Set for re-prompt.
        }
        else { 
            numberInput = Integer.parseInt(num1);

            // ... do whatever you want to do with numberInput, for example ....
            guesses[counter] = numberInput;
        }
    }
}

// Display User's LIMITED guesses:
StringBuilder sb = new StringBuilder();
sb.append("<html>The <font color=red><b>").append(LIMIT).
        append("</b></font> Guesses supplied by User are:<br><br>");

for (int i = 0; i < guesses.length; i++) {
    sb.append("Guess #").append((i + 1)).append(":  <font color=blue>").append(guesses[i]).append("</font><br>");
}
sb.append("</html>");

JOptionPane.showMessageDialog(null, sb.toString(), "Guesses Provided", 
                              JOptionPane.INFORMATION_MESSAGE);

如您所见,向用户提供有关输入失败的详细信息需要更多的代码。如果您决定只需要一个简单的“无效输入”,则可以删除所有这些代码。信息。从本质上讲,这迫使用户更仔细地阅读提供的提示,例如:

int LIMIT = 3;
int numberInput;
int[] guesses = new int[LIMIT];
String num1;
JOptionPane.showMessageDialog(null, "<html>You will be prompted three times "
        + "to supply<br>a positive <font color=red><b>single digit</b></font> "
        + "number.</html>", "Information", JOptionPane.INFORMATION_MESSAGE);
for (int counter = 0; counter < LIMIT; counter++) {
    num1 = "";
    while (num1.equals("")) {
        num1 = JOptionPane.showInputDialog(null, "Please input Guess #" + (counter + 1), 
                                           "Guess #" + (counter + 1),JOptionPane.QUESTION_MESSAGE);
        // Does num1 contain null?
        if (num1 == null){
            if (JOptionPane.showConfirmDialog(null,
                    "<html>You <font color=blue>canceled</font> your input!<br>"
                    + "Do you want to quit?</html>", "Quit",
                    JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
                System.exit(0);
            }
            num1 = ""; // Set for re-prompt.
        }
        else if (!num1.matches("\\d")) {
            JOptionPane.showMessageDialog(null, "<html><center><font size=5 color=red>Invalid Input Supplied!</font><br>" +
                    "<font size=5 color=blue>\"" + num1 + "\"</font></center><br>" +
                    "You must provide a single Integer value between<br>0 and 9 "
                    + "(inclusive).</html>", "Invalid Input!", JOptionPane.WARNING_MESSAGE);
            num1 = "";
        }
        else { 
            numberInput = Integer.parseInt(num1);

            // ... do whatever you want to do with numberInput, for example ....
            guesses[counter] = numberInput;
        }        
    }
}

// Display User's LIMITED guesses:
StringBuilder sb = new StringBuilder();
sb.append("<html>The <font color=red><b>").append(LIMIT).
        append("</b></font> Guesses supplied by User are:<br><br>");

for (int i = 0; i < guesses.length; i++) {
    sb.append("Guess #").append((i + 1)).append(":  <font color=blue>").append(guesses[i]).append("</font><br>");
}
sb.append("</html>");
JOptionPane.showMessageDialog(null, sb.toString(), "Guesses Provided", 
                                  JOptionPane.INFORMATION_MESSAGE);

上面代码中的else if语句(!num1.matches("\\d))的条件要特别注意。在此,String#matches()方法的使用与较小的Regular Expression表达式"\\d"一起使用。此表达式告诉matches()方法查看我们匹配的字符串(在[[num1中)是否为单数位字符串数值(例如:“ 5”)。因此,else if语句在问什么:

else if

num1中包含的字符串为NOT(!)一位数字的字符串数值,然后在花括号({...})中运行代码。这基本上涵盖了除null外的所有输入失败(因为我们将其作为quit选项处理),并且String#matches()方法将不接受null。 如果您不想使用

quit

选项,那么您只需在代码中使用一个if语句:if (num1 == null || !num1.matches("\\d")) { ... }
© www.soinside.com 2019 - 2024. All rights reserved.