Java程序在Eclipse正常运行,ZyBooks读取文件触发NumberFormatException报错求助
解决Java程序在ZyBooks中触发
NumberFormatException: empty String的问题 我帮你分析下这个问题——你在Eclipse里能正常运行,但到ZyBooks就报错,核心原因是文件读取和字符串分割的逻辑在不同环境下的行为不一致,导致解析空字符串时抛出异常。咱们一步步拆解并修复它:
问题根源分析
报错指向Double.parseDouble(values[0])这一行,说明values数组里出现了空字符串元素,主要有两个诱因:
- 字符串分割逻辑有缺陷:你用
split(" ")分割数据行,但这个方法会把连续空格、行首/行尾的空格解析成空字符串。比如文件里的行是"1500 4 A"(多个空格分隔),split(" ")会得到["1500", "", "4", "", "", "A"];如果行开头有空格,第一个元素直接是空字符串,触发解析异常。 - 环境间的文件格式差异:ZyBooks用的是类Linux环境,换行符是LF,而你本地Eclipse可能用的是Windows的CRLF,或者测试文件里包含空行,导致
myReader.nextLine()读取到空字符串,分割后全是空元素。
修复步骤&代码优化
1. 修复字符串分割逻辑
把split(" ")替换成split("\\s+"),这个正则表达式会匹配任意数量的空白字符(包括空格、制表符),自动忽略连续空白,不会生成空元素。
2. 添加空行和格式校验
读取行后先做trim处理,跳过空行;分割后检查数组长度是否符合预期(至少3个元素:金额、年限、计息代码),避免后续解析出错。
3. 用try-with-resources管理资源
原代码手动关闭myReader,如果遇到异常可能导致流未关闭,改用try-with-resources可以自动管理文件流,更安全。
4. 优化Scanner资源使用
InputFileName()里的Scanner用完没关闭,虽然不影响当前报错,但用try-with-resources关闭更规范。
修复后的核心代码片段
// 修改后的openFile方法 public static void openFile(String filename) { // 用try-with-resources自动关闭文件流 try (Scanner myReader = new Scanner(new File(filename))) { if (myReader.hasNextLine()) { System.out.println("Name Years Deposit Amount Interest Earned Total"); while (myReader.hasNextLine()) { String name = myReader.nextLine().trim(); // 跳过空的姓名行 if (name.isEmpty()) { continue; } // 检查是否有对应的数据行 if (!myReader.hasNextLine()) { System.out.println("Warning: 姓名「" + name + "」缺少对应数据行"); break; } String data = myReader.nextLine().trim(); // 跳过空的数据行 if (data.isEmpty()) { System.out.println("Warning: 姓名「" + name + "」对应数据行为空"); continue; } // 用\\s+分割,避免空元素 String[] values = data.split("\\s+"); // 校验数据格式是否合法 if (values.length < 3) { System.out.println("Warning: 姓名「" + name + "」的数据格式错误:" + data); continue; } try { double Amount = Double.parseDouble(values[0]); double Deposited_Years = Double.parseDouble(values[1]); char code = values[2].charAt(0); // 后续计算逻辑保持不变 double rate = InterestRate(Deposited_Years); int n = noOfTimeInterest(code); double total = EarnedTotal(Amount, rate, n, Deposited_Years); total = (double) Math.round(total * 100) / 100; double total_Interest = total - Amount; total_Interest = (double) Math.round(total_Interest * 100) / 100; System.out.printf("%-20s %-10.0f %10s %15s %15s %n", name, Deposited_Years, "$" + Amount, "$" + total_Interest, "$" + total); } catch (NumberFormatException e) { System.out.println("Warning: 姓名「" + name + "」的数据解析失败:" + data); } } System.out.println("Thank you for using interest calculation program. Have a nice day"); } else { System.out.println("There was no data in the file. Program terminated."); } } catch (FileNotFoundException e) { System.out.println("Could not open file. Program terminated."); } } // 优化后的InputFileName方法 public static String InputFileName() { System.out.print("Enter file name:"); // 用try-with-resources自动关闭Scanner try (Scanner sc = new Scanner(System.in)) { return sc.nextLine().trim(); } }
额外小建议
- 测试文件时确保格式严格:一行姓名、一行数据(金额+年限+计息代码,用任意空白分隔),不要有空行或格式错误的行。
- 多练习Java的异常处理,适当捕获异常并给出提示,能让程序更健壮,不会一出错就直接崩溃。
内容的提问来源于stack exchange,提问作者NKl
相关产品推荐
相关产品推荐

