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

Java程序抛出NumberFormatException,如何修复销售报表程序?

Java NumberFormatException 错误修复方案

报错信息

Exception in thread "main" java.lang.NumberFormatException: For input string: ""
    at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.base/java.lang.Integer.parseInt(Integer.java:662)
    at java.base/java.lang.Integer.parseInt(Integer.java:770)
    at Main.displayBody(Main.java:27)
    at Main.main(Main.java:11)

需求说明

需编写包含main()、displayHeader()、displayBody()、displayFooter()的程序:

  • main()调用另外三个方法
  • displayHeader()打印报表头部
  • displayBody()读取Lab6Data.txt,打印主体并累计总数,直到读取到quit
  • displayFooter()打印总计

预期输出:

Sales Report
Name..........Amount
Abbot.......2,685
Coswell.....1,745
Freedwick...6,283
Gibson......5,453
Total......16,166

Lab6Data.txt 内容

Abbot
2685
Coswell
1745
Freedwick
6283
Gibson
5453
quit
0

用户编写的代码

import java.util.Scanner;

class Main {
public static void main(String[] args) {
    displayHeader();
    displayBody();       
    displayFooter();
 }
public static void displayHeader() {
    String header = "";
    Scanner sc = new Scanner(System.in);
    System.out.println("Sales Report");
    System.out.println("Name......Amount"); 
 }
 public static void displayBody() {
    String throwaway = "";
    Scanner sc = new Scanner(System.in);
    while (sc.hasNextLine()) {
       String name = sc.nextLine();
       throwaway = sc.nextLine();
       if (name.equals("quit")) break;
       int amount = Integer.parseInt(sc.nextLine());
       throwaway = sc.nextLine();
       System.out.println("name......"+name+" amount"+amount);
    }
 }
 public static void displayFooter() {

    String totalSum = "";
    Scanner sc = new Scanner(System.in);
    while(sc.hasNextLine()){
      int sum =0;
      int total = Integer.parseInt(sc.nextLine());
      sum += total;
       System.out.println("Total....." + sum);
    }         
 }
 }

问题分析与修复步骤

1. 核心错误原因

报错源于displayBody()中错误地重复调用sc.nextLine(),跳过了有效数据行,导致Integer.parseInt()读取到空字符串或不符合要求的内容。原代码每次循环读取4行,但实际数据是姓名、金额交替存储,完全不需要额外的"丢弃行"操作。

2. 具体修复点

(1)修正displayBody()的读取逻辑

  • 移除所有多余的throwaway = sc.nextLine();语句,每次循环仅读取姓名行和对应的金额行
  • 新增静态变量存储累计总金额,让displayBody()和displayFooter()可以共享数据
  • 读取目标文件而非标准输入,原代码错误地读取控制台输入,需改为读取Lab6Data.txt
  • 格式化金额输出,添加千位分隔符并对齐格式,匹配预期输出

(2)清理displayHeader()冗余代码

  • 移除无用的Scanner sc = new Scanner(System.in);,该方法仅需打印内容,无需读取输入

(3)重构displayFooter()逻辑

  • 无需重新读取输入,直接使用displayBody()累计的总金额,格式化输出总计

3. 完整修复后的代码

import java.util.Scanner;
import java.text.NumberFormat;
import java.util.Locale;

class Main {
    // 静态变量存储总金额,实现方法间数据共享
    private static int totalAmount = 0;

    public static void main(String[] args) {
        displayHeader();
        displayBody();       
        displayFooter();
    }

    public static void displayHeader() {
        System.out.println("Sales Report");
        System.out.println("Name..........Amount"); 
    }

    public static void displayBody() {
        // 读取Lab6Data.txt文件,使用try-with-resources自动关闭流
        try (Scanner sc = new Scanner(Main.class.getResourceAsStream("Lab6Data.txt"))) {
            NumberFormat amountFormatter = NumberFormat.getNumberInstance(Locale.US);
            while (sc.hasNextLine()) {
                String name = sc.nextLine().trim();
                // 跳过可能存在的空行
                if (name.isEmpty()) continue;
                // 遇到quit则终止循环
                if (name.equals("quit")) break;
                // 读取对应金额行,避免无数据时抛出异常
                if (!sc.hasNextLine()) break;
                String amountStr = sc.nextLine().trim();
                int amount = Integer.parseInt(amountStr);
                totalAmount += amount;
                // 格式化对齐输出
                System.out.printf("%-10s%s%n", name, amountFormatter.format(amount));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void displayFooter() {
        NumberFormat amountFormatter = NumberFormat.getNumberInstance(Locale.US);
        System.out.printf("Total......%s%n", amountFormatter.format(totalAmount));
    }
}

4. 关键说明

  • 文件读取修正:确保Lab6Data.txt与编译后的class文件在同一目录,使用类加载器流读取文件
  • 异常防护:添加空行跳过逻辑、数据存在性判断,避免因文件格式问题抛出异常
  • 输出格式化:用printf实现文本对齐,NumberFormat生成带千位分隔符的金额格式
  • 资源自动管理:使用try-with-resources语法自动关闭Scanner,避免资源泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 12:50:29