You need to enable JavaScript to run this app. Java如何将含姓名与两个数值的字符串拆分为String和两个double变量
优惠活动
大模型
产品
解决方案
定价
更多

Java如何将含姓名与两个数值的字符串拆分为String和两个double变量

错误原因分析

你遇到的java.util.InputMismatchException异常,本质是Scanner尝试读取的内容和你指定的目标数据类型不匹配,异常抛出点在nextDouble()调用,说明此时Scanner拿到的分词结果不是合法的double格式,核心错误来自两处:

  1. Scanner初始化位置错误
    你仅在进入while循环前,用读取到的第一行文本创建了一次Scanner对象。后续循环中你虽然通过inFile.readLine()拿到了新的行内容,但并没有把新行同步给Scanner处理。当第一行的4个分词(名、姓、两个double数值)读完后,Scanner已经没有可解析的有效内容,下一轮循环再调用scan.next()或scan.nextDouble()时,要么直接读取失败,要么拿到的内容不是预期的数值类型,自然触发类型不匹配异常。
  2. 缺少异常边界判断(次要原因)
    你没有提前判断当前行是否有足够的分词、分词是否符合数值格式,哪怕出现某行内容残缺、格式错误的情况,程序也会直接抛出异常。
    另外还有低概率的区域格式问题:如果你的系统默认区域设置的小数分隔符是逗号而非点,读取3.36这类带小数点的数值时也会触发该异常。
修复方案

最简单的修改是把Scanner的创建逻辑挪到while循环内部,每读取一行就创建一个新的Scanner绑定当前行内容,修改后的代码如下:

public Roster(String filename) {
    players = new ArrayList<Player>();
    
    try (FileReader fr = new FileReader(filename);
         BufferedReader inFile = new BufferedReader(fr)) {
        
        String line = inFile.readLine();
        
        while(line != null) {
            // 每一行单独创建Scanner处理
            Scanner scan = new Scanner(line);
            String firstName = scan.next();
            String lastName = scan.next();
            double attackStat = scan.nextDouble();
            double blockStat = scan.nextDouble();
            String name = firstName + " " + lastName;
            Player newPlayer = new Player(name, attackStat, blockStat);
            players.add(newPlayer);
            scan.close();
            line = inFile.readLine();
        }
        
    } catch (IOException e) {
        System.out.println(e);
    }
}

如果确认是区域格式问题,可以在创建Scanner后指定区域设置:
scan.useLocale(Locale.US);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 18:54:04