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

Java Scanner成绩平均值计算程序逻辑异常排查求助

问题分析与修复方案

嘿,你的问题根源确实和Scanner的使用逻辑有关——你现在的代码里,每次循环先取出一个token到str,但后续所有判断都是在检查下一个token,而不是当前手里的str,这就导致所有处理都“滞后”了一步,自然需要输入两次指令才能触发预期行为。

具体错误点拆解

  1. ID判断逻辑错位:你用sc.hasNext("[0-9]{6}")检查下一个token是否是6位ID,但此时str已经是当前取出的token了,这会导致你把非ID的内容赋值给AM,而真正的ID要等到下一次循环才会被处理。
  2. "end"和数值的判断同理:比如当输入"end"时,你取出的str就是"end",但代码却在检查下一个token是否是"end",这时候下一个token不存在,自然不会触发重置逻辑;直到你再输入一次"end",上一次的"end"才会被误打误撞处理。
  3. 科目名称被忽略的同时,数值处理也偏移:你处理浮点数时,直接取了下一个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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:26:40