Java Scanner成绩平均值计算程序逻辑异常排查求助
问题分析与修复方案
嘿,你的问题根源确实和Scanner的使用逻辑有关——你现在的代码里,每次循环先取出一个token到str,但后续所有判断都是在检查下一个token,而不是当前手里的str,这就导致所有处理都“滞后”了一步,自然需要输入两次指令才能触发预期行为。
具体错误点拆解
- ID判断逻辑错位:你用
sc.hasNext("[0-9]{6}")检查下一个token是否是6位ID,但此时str已经是当前取出的token了,这会导致你把非ID的内容赋值给AM,而真正的ID要等到下一次循环才会被处理。 - "end"和数值的判断同理:比如当输入"end"时,你取出的
str就是"end",但代码却在检查下一个token是否是"end",这时候下一个token不存在,自然不会触发重置逻辑;直到你再输入一次"end",上一次的"end"才会被误打误撞处理。 - 科目名称被忽略的同时,数值处理也偏移:你处理浮点数时,直接取了下一个token,当前的
str(科目名称)虽然不需要计算,但你的逻辑相当于跳过了一个token,进一步加剧了错位。
修正后的代码
我们调整逻辑,所有判断都基于当前取出的str,而不是去预判下一个token:
package averagemarks; import java.util.*; class AverageMarks { public static void main(String args[]) { Scanner sc = new Scanner(System.in); sc.useDelimiter("\\s+"); sc.useLocale(Locale.US); int count = 0; double sum = 0.0; String studentId; System.out.println("Give string: "); while (sc.hasNext()) { String str = sc.next(); // 先判断是否是6位学生ID if (str.matches("[0-9]{6}")) { studentId = str; System.out.println("Student ID: " + studentId); // 输入000000终止程序 if (studentId.equals("000000")) { break; } } // 判断是否是结束标记"end" else if (str.equals("end")) { if (count == 0) { System.out.println("No scores to calculate average."); } else { System.out.println("Average is " + sum / count); } // 重置统计变量 count = 0; sum = 0.0; } // 判断是否是成绩(浮点数) else { try { double score = Double.parseDouble(str); sum += score; count++; } catch (NumberFormatException e) { // 不是ID、end、成绩的内容(比如科目名称),直接跳过 continue; } } } sc.close(); } }
关键修改说明
- 用
str.matches("[0-9]{6}")直接判断当前token是否是6位ID,不再依赖sc.hasNext()预判下一个。 - 直接检查
str.equals("end"),确保输入"end"时立即触发平均值计算和变量重置。 - 用
try-catch解析浮点数,自动跳过科目名称这类非数值内容,逻辑更清晰。 - 增加了
count == 0的判断,避免除以0的异常。
这样修改后,输入一次"end"就能立即重置,输入一次"000000"就能终止程序,完全符合需求啦~
内容的提问来源于stack exchange,提问作者PGkiokas
相关产品推荐
相关产品推荐

