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
相关产品推荐
相关产品推荐

