java.lang.StringIndexOutOfBoundsException: String index out of range: 0

img

一个循环结构,第一次循环时,调用这个方法能正常运行。第二次循环调用这个方法就出错了,我测试之后,发现readKeyBoard()方法里的while循环里的语句在第二次就没运行,字符串的长度就直接是0了,控制台输入直接没运行,该怎么改呢?

public static char readMenuSelection() {
        char c;
        for (; ; ) {
            String str = readKeyBoard(1, false);
            c = str.charAt(0);
            if (c != '1' && c != '2' && 
                c != '3' && c != '4' && c != '5') {
                System.out.print("选择错误,请重新输入:");
            } else break;
        }
        return c;
    }


 private static String readKeyBoard(int limit, boolean blankReturn) {
        String line = "";

        while (scanner.hasNextLine()) {
            line = scanner.nextLine();
            if (line.length() == 0) {
                if (blankReturn) return line;
                else continue;
            }

            if (line.length() < 1 || line.length() > limit) {
                System.out.print("输入长度(不大于" + limit + ")错误,请重新输入:");
                continue;
            }
            break;
        }

        return line;
    }


在c = str.charAt(0)之前判断下str的长度,长度小于1时continue。代码没有错,看下你是怎么输入的

参考gpt:
根据你提供的代码和描述,第二次循环调用readKeyBoard()方法时出现了问题,循环内的语句没有执行,导致字符串的长度直接变为0。可能的原因是scanner对象在第一次循环结束后被关闭了,导致无法再次读取输入。

为了解决这个问题,你可以尝试在readKeyBoard()方法中重新创建一个新的Scanner对象来读取输入,确保每次循环都能够正常读取输入。以下是修改后的代码:

private static String readKeyBoard(int limit, boolean blankReturn) {
    String line = "";

    Scanner scanner = new Scanner(System.in); // 创建新的Scanner对象

    while (scanner.hasNextLine()) {
        line = scanner.nextLine();
        if (line.length() == 0) {
            if (blankReturn) return line;
            else continue;
        }

        if (line.length() < 1 || line.length() > limit) {
            System.out.print("输入长度(不大于" + limit + ")错误,请重新输入:");
            continue;
        }
        break;
    }

    // 关闭Scanner对象
    scanner.close();

    return line;
}

通过在readKeyBoard()方法内部创建一个新的Scanner对象,并在循环结束后关闭它,确保每次循环都可以正常读取输入。这样应该能够解决第二次循环调用时的问题。

另外,你也可以考虑将Scanner对象作为参数传递给readKeyBoard()方法,而不是在方法内部创建和关闭它。这样可以更好地控制Scanner的生命周期,以避免重复创建和关闭的开销。