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

Java输入多词字符串触发java.lang.NumberFormatException的问题

问题描述

在Java费用统计程序中输入带空格的项目名称(如Chicken rice)时,程序会把第二个词识别成金额输入,调用Integer.valueOf()时抛出NumberFormatException:

Exception in thread "main" java.lang.NumberFormatException: For input string: "rice"    at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67) at java.base/java.lang.Integer.parseInt(Integer.java:668)   at java.base/java.lang.Integer.valueOf(Integer.java:999)     at Sampleproject1/t4.Main.main(Main.java:65)

当前使用的代码如下:

import java.util.*;

class Expense implements Comparable<Expense>{
    
    String expenseCategory;
    Integer amount;
    
    
    public String getExpenseCategory() {
        return expenseCategory;
    }
    public void setExpenseCategory(String expenseCategory) {
        this.expenseCategory = expenseCategory;
    }
    public Integer getAmount() {
        return amount;
    }
    public void setAmount(Integer amount) {
        this.amount = amount;
    }   
    
    public Expense(String expC , Integer amount) {
        this.expenseCategory=expC;
        this.amount = amount;
    }
        
    public String toString() {
        return expenseCategory+ " " +amount;
    }
        
    public int compareTo(Expense e) {
        if(amount>e.amount){    
            return 1;    
        }else if(amount<e.amount){    
            return -1;    
        }else{    
        return 0;    
        } 
    }
}

public class Main {
    
    public static void main(String[] args) {
        
        Scanner sc = new Scanner(System.in);
        
        TreeSet<Expense> set1 = new TreeSet<Expense>();

        int tamount=0;
        
        while(true) {
            System.out.println("Enter item");
            String expC = sc.next();
            System.out.println("Enter amount(Dinar)");
            String amt = sc.next();
            tamount = tamount + Integer.valueOf(amt);
            set1.add(new Expense(expC,Integer.valueOf(amt)));
            System.out.println("Do you want to continue(yes/no):");
            String cond = sc.next();
            if(cond.equals("no")) {
                break;
            }else {continue;}
        }
        System.out.println("Total dinar required is:");
        System.out.println("Category    Amount(Dinar)");
        Iterator x = set1.descendingIterator();
            
        while(x.hasNext()) {
            System.out.println(x.next());
        }
                
        System.out.println("Total amount needed in Dinar:"+ tamount);
        System.out.println("Total amount needed in Rupees:"+ tamount*18.565);   
    }       
}

期望实现的输出效果:

Enter item
Fried Rice
Enter amount(Dinar)
20
Do you want to continue(yes/no):
yes
Enter item
Chicken Lollipop
Enter amount(Dinar)
25
Do you want to continue(yes/no):
yes
Enter item
Coffee
Enter amount(Dinar)
5
Do you want to continue(yes/no):
no
Total dinar required is:
Item           Amount(Dinar)  
Chicken Lollipop25             
Fried Rice     20              
Coffee         5               
Total amount needed in Dinar: 50
Total amount needed in Rupees: 928.25

尝试用Scanner.nextLine()解决多词输入问题时,出现部分输入被跳过的情况,需要解决该问题。

问题原因
  1. sc.next()默认以空格作为分隔符,只能读取到空格前的第一个词,后续内容会被当成下一个输入项,导致金额读取到项目名的后续词,触发类型转换异常。
  2. 当next()和nextLine()混用时,next()读取完内容后会留下换行符在输入缓冲区,后续的nextLine()会直接读取这个空换行符,导致输入被跳过。
解决方案

统一使用nextLine()读取输入,同时增加输入合法性校验提升程序健壮性,修改后的完整代码如下:

import java.util.*;

class Expense implements Comparable<Expense> {
    String expenseCategory;
    Integer amount;

    public String getExpenseCategory() {
        return expenseCategory;
    }

    public void setExpenseCategory(String expenseCategory) {
        this.expenseCategory = expenseCategory;
    }

    public Integer getAmount() {
        return amount;
    }

    public void setAmount(Integer amount) {
        this.amount = amount;
    }

    public Expense(String expC, Integer amount) {
        this.expenseCategory = expC;
        this.amount = amount;
    }

    @Override
    public String toString() {
        // 格式化输出实现对齐效果
        return String.format("%-15s %d", expenseCategory, amount);
    }

    @Override
    public int compareTo(Expense e) {
        // 直接复用Integer的compareTo方法更简洁
        return amount.compareTo(e.amount);
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        TreeSet<Expense> set1 = new TreeSet<>();
        int tamount = 0;

        while (true) {
            System.out.println("Enter item");
            // 读取完整项目名称,去除前后空格
            String expC = sc.nextLine().trim();
            // 处理空输入情况
            while (expC.isEmpty()) {
                System.out.println("Item name cannot be empty, please enter again");
                expC = sc.nextLine().trim();
            }

            System.out.println("Enter amount(Dinar)");
            Integer amt = null;
            // 循环直到输入合法正整数
            while (amt == null) {
                String amtStr = sc.nextLine().trim();
                try {
                    amt = Integer.valueOf(amtStr);
                    if (amt <= 0) {
                        System.out.println("Amount must be positive, please enter again");
                        amt = null;
                    }
                } catch (NumberFormatException e) {
                    System.out.println("Invalid amount, please enter an integer");
                }
            }

            tamount += amt;
            set1.add(new Expense(expC, amt));

            System.out.println("Do you want to continue(yes/no):");
            String cond = "";
            // 确保输入只能是yes/no
            while (!cond.equalsIgnoreCase("yes") && !cond.equalsIgnoreCase("no")) {
                cond = sc.nextLine().trim();
                if (!cond.equalsIgnoreCase("yes") && !cond.equalsIgnoreCase("no")) {
                    System.out.println("Please enter yes or no");
                }
            }

            if (cond.equalsIgnoreCase("no")) {
                break;
            }
        }

        System.out.println("Total dinar required is:");
        System.out.println(String.format("%-15s %s", "Item", "Amount(Dinar)"));
        Iterator<Expense> x = set1.descendingIterator();
        while (x.hasNext()) {
            System.out.println(x.next());
        }

        System.out.println("Total amount needed in Dinar: " + tamount);
        // 格式化输出卢比金额保留两位小数
        System.out.printf("Total amount needed in Rupees: %.2f%n", tamount * 18.565);
    }
}

关键修改点

  • 全部替换sc.next()为sc.nextLine(),配合trim()读取完整的带空格项目名称。
  • 增加输入校验:项目名非空、金额为正整数、继续指令只能是yes/no,避免非法输入导致的异常。
  • 重写toString()方法用String.format()格式化输出,实现项目与金额的对齐效果。
  • 简化compareTo()方法,直接调用Integer的内置比较方法,代码更规范。

内容的提问来源于stack exchange,提问作者Tharun S M

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 15:25:04