You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Scanner.nextLine()问题:输入含错误数据时无法重置当前行输入

Java非方形二维数组输入异常时无法重置当前行

我写了一段Java代码,用来通过Scanner创建非方形二维数组:

public static double[][] run(Scanner s){
    System.out.print("The number of rows non square array: "); 
    int length = s.nextInt();
    double Arr[][] = new double[length][];
    for(int i=0; i<length; i++) {
        System.out.print("Input: ");      
        int length2 = i+1;
        Arr[i] = new double[length2];
        for(int j=0; j< length2; j++) {
            while(true) {
                try {  
                    Arr[i][j] = s.nextDouble();
                    break;
                }
                catch(InputMismatchException e) {
                    System.out.println("That's not correct!");
                    System.out.print("Input: ");
                    s.nextLine();
                    continue;
                }
            }
        }
    }
    
    return Arr;
}

测试时发现问题:输入类似“4 5 6a”这种混合有效数字和错误格式的内容时,程序捕获InputMismatchException后,已经读取的4.0、5.0会留在数组对应位置,最终该行变成[4.0,5.0,7.0]。但我希望遇到这种情况时重置当前行的输入,让用户重新输入整行的正确数据,最终该行应该是比如[7.0,8.0,9.0]。要求必须用try-catch处理异常,请问问题出在哪?


问题根源

你的代码是逐个元素处理输入并捕获异常,遇到错误输入时,只是跳过当前错误的输入项,但之前已经成功读取的元素已经写入数组了,没有回退到当前行的起始状态重新输入整行。而且Scanner的nextDouble()在解析失败时,错误的输入标记会留在输入流中,s.nextLine()只能清空当前剩余的输入,但已经写入数组的元素没法撤回,导致整行输入不完整却保留了部分有效数据。

解决方案:整行捕获异常,重置当前行

要实现“整行错误就重新输入整行”的逻辑,需要把当前行的所有元素读取操作放到同一个try块中,一旦该行任何位置出现异常,就放弃当前行已经写入的所有数据,让用户重新输入整行。

修改后的代码如下:

import java.util.InputMismatchException;
import java.util.Scanner;

public static double[][] run(Scanner s){
    System.out.print("The number of rows non square array: "); 
    int length = s.nextInt();
    // 读取nextInt()后留下的换行符,避免后续读取整行时拿到空字符串
    s.nextLine();
    double Arr[][] = new double[length][];
    
    for(int i=0; i<length; i++) {
        int length2 = i+1;
        boolean isRowValid = false;
        while(!isRowValid) {
            System.out.print("Input: ");
            Arr[i] = new double[length2];
            try {
                // 一次性读取整行,再拆分处理
                String line = s.nextLine().trim();
                String[] parts = line.split("\\s+");
                // 检查输入的元素数量是否符合当前行要求
                if(parts.length != length2) {
                    throw new InputMismatchException("元素数量不符");
                }
                // 逐个解析元素
                for(int j=0; j<length2; j++) {
                    Arr[i][j] = Double.parseDouble(parts[j]);
                }
                isRowValid = true; // 整行都正确,标记为有效
            } catch (Exception e) {
                System.out.println("That's not correct! 请重新输入整行");
                // 不需要额外清空输入流,因为已经用nextLine()读取了整行
            }
        }
    }
    
    return Arr;
}

改动说明

  • 读取行数后调用s.nextLine():因为nextInt()只会读取数字,不会读取后面的换行符,不处理的话后续nextLine()会先读到空字符串,导致逻辑出错。
  • 给每行加一个isRowValid标记:用来判断当前行是否输入正确,不正确就循环让用户重新输入。
  • 整行读取+解析:先用nextLine()读取整行输入,拆分后检查元素数量,再逐个解析为double。任何一步出错(数量不对、格式错误)都会触发catch,此时当前行的数组会被重新初始化,用户需要重新输入整行。
  • 统一异常捕获:不管是格式错误还是数量不符,都视为整行输入错误,提示用户重新输入。

内容的提问来源于stack exchange,提问作者Cuny

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 06:13:43