Java蛋糕工厂程序读取文件时抛出InputMismatchException异常求助
问题:InputMismatchException异常排查与解决
异常现象
运行TheCupcakeFactory程序时,输出欢迎消息后抛出InputMismatchException,程序终止执行。异常堆栈信息如下:
Exception in thread "main" java.util.InputMismatchException at java.base/java.util.Scanner.throwFor(Scanner.java:939) at java.base/java.util.Scanner.next(Scanner.java:1594) at java.base/java.util.Scanner.nextInt(Scanner.java:2258) at java.base/java.util.Scanner.nextInt(Scanner.java:2212) at TheCupcakeFactory.main(TheCupcakeFactory.java:35)
相关代码与文件内容
TheCupcakeFactory主类代码
import java.io.FileReader; import java.io.IOException; import java.util.Scanner; public class TheCupcakeFactory { private static Scanner inputFile; /* *Diego Molina Salinas *CS160 Fall 2023 *Project 4: The Cupcake Factory Sales * */ public static void main(String[] args) throws IOException { Cupcake cupcakeCS = new Cupcake(); Cupcake cupcakeAP = new Cupcake(); Cupcake cupcakeBF = new Cupcake(); Cupcake cupcakeBS = new Cupcake(); Cupcake cupcakeBW = new Cupcake(); Cupcake [] cupcakes = {cupcakeCS, cupcakeAP, cupcakeBF, cupcakeBS, cupcakeBW}; System.out.println("Welcome to the Cupcake Factory Sales Registry!!"); FileReader file = new FileReader("FreshCupcakes.txt"); inputFile = new Scanner(file); //This is setting the Chocolate Strawberry Cupcake cupcakeCS.setFlavor(inputFile.next()); cupcakeCS.setDescription("Moist chocolate cake filled with strawberry jam, topped with strawberry buttercream dipped in chocolate."); cupcakeCS.setUnitsOnHand(inputFile.nextInt()); cupcakeCS.setPrice(2.75); //This is setting the Apple Pie Cupcake cupcakeAP.setFlavor(inputFile.next()); cupcakeAP.setDescription("Moist vanilla cake filled with apple pie filling; topped with cream cheese icing, apple pie filling, and cinnamon streusel"); cupcakeAP.setUnitsOnHand(inputFile.nextInt()); cupcakeAP.setPrice(3.25); //This is setting the Butterfinger Cupcake cupcakeBF.setFlavor(inputFile.next()); cupcakeBF.setDescription("Moist chocolate cake filled and topped with our peanut butter icing and Butterfinger candy."); cupcakeBF.setUnitsOnHand(inputFile.nextInt()); cupcakeBF.setPrice(2.95); //This is setting the Banana Split Cupcake cupcakeBS.setFlavor(inputFile.next()); cupcakeBS.setDescription("Moist chocolate cake filled with banana filling, topped with our vanilla buttercream with sprinkles, cherry and chocolate drizzle on top."); cupcakeBS.setUnitsOnHand(inputFile.nextInt()); cupcakeBS.setPrice(3.15); //This is setting the Black & White Cupcake cupcakeBW.setFlavor(inputFile.next()); cupcakeBW.setDescription(" Moist vanilla cupcake, topped with our rich fudge icing"); cupcakeBW.setUnitsOnHand(inputFile.nextInt()); cupcakeBW.setPrice(3.50); for (Cupcake cupcake : cupcakes) { System.out.println(cupcake); } } }
Cupcake类代码
public class Cupcake { String flavor; String description; int unitsOnHand; double price; public Cupcake() { // TODO Auto-generated constructor stub this.flavor = ""; this.description = ""; this.unitsOnHand = 0; this.price = 0.0; } public String getFlavor() { return flavor; } public void setFlavor(String flavor) { this.flavor = flavor; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public int getUnitsOnHand() { return unitsOnHand; } public void setUnitsOnHand(int unitsOnHand) { this.unitsOnHand = unitsOnHand; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public void newUnitsOnHand(int quantity) { unitsOnHand = unitsOnHand - quantity; } @Override public String toString() { return flavor + ": \t\t $" + price + " - " + description; } }
FreshCupcakes.txt文件内容
Chocolate Strawberry 25 Apple Pie 15 Butterfinger 25 Banana Split 30 Black & White 50
问题原因
代码中使用inputFile.next()读取蛋糕口味,但部分口味由多个单词组成(如Chocolate Strawberry)。Scanner.next()默认以空格为分隔符,只会读取到第一个空格前的内容(比如Chocolate),后续调用inputFile.nextInt()时,读取到的是第二个单词(Strawberry),而非预期的数字,因此抛出InputMismatchException。
解决方案
推荐采用按行读取文件的方式,拆分每行内容获取完整口味名称和库存数量,这种方法适配任意单词数的口味名称,鲁棒性更强。
修改主类中的文件读取逻辑如下:
FileReader file = new FileReader("FreshCupcakes.txt"); inputFile = new Scanner(file); // 按行读取并处理每个蛋糕的信息 int index = 0; while (inputFile.hasNextLine()) { String line = inputFile.nextLine().trim(); if (line.isEmpty()) continue; // 拆分每行:最后一个空格前的内容为口味,后面的为库存数量 int lastSpacePos = line.lastIndexOf(" "); String flavor = line.substring(0, lastSpacePos).trim(); int units = Integer.parseInt(line.substring(lastSpacePos + 1).trim()); cupcakes[index].setFlavor(flavor); cupcakes[index].setUnitsOnHand(units); index++; } // 保持原有的描述和价格设置逻辑 cupcakeCS.setDescription("Moist chocolate cake filled with strawberry jam, topped with strawberry buttercream dipped in chocolate."); cupcakeCS.setPrice(2.75); cupcakeAP.setDescription("Moist vanilla cake filled with apple pie filling; topped with cream cheese icing, apple pie filling, and cinnamon streusel"); cupcakeAP.setPrice(3.25); cupcakeBF.setDescription("Moist chocolate cake filled and topped with our peanut butter icing and Butterfinger candy."); cupcakeBF.setPrice(2.95); cupcakeBS.setDescription("Moist chocolate cake filled with banana filling, topped with our vanilla buttercream with sprinkles, cherry and chocolate drizzle on top."); cupcakeBS.setPrice(3.15); cupcakeBW.setDescription(" Moist vanilla cupcake, topped with our rich fudge icing"); cupcakeBW.setPrice(3.50); for (Cupcake cupcake : cupcakes) { System.out.println(cupcake); }
如果不想修改整体逻辑,也可以针对每个多单词口味,手动拼接读取的单词:
// 读取Chocolate Strawberry口味 cupcakeCS.setFlavor(inputFile.next() + " " + inputFile.next()); cupcakeCS.setUnitsOnHand(inputFile.nextInt()); // 读取Apple Pie口味 cupcakeAP.setFlavor(inputFile.next() + " " + inputFile.next()); cupcakeAP.setUnitsOnHand(inputFile.nextInt()); // 其余单单词口味保持原逻辑 cupcakeBF.setFlavor(inputFile.next()); cupcakeBF.setUnitsOnHand(inputFile.nextInt());
但这种方法仅适用于已知口味单词数的场景,扩展性较差。
内容的提问来源于stack exchange,提问作者moemoe
相关产品推荐
相关产品推荐

