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

Java程序无法输出及InputMismatchException错误排查求助

解决Java程序的主方法缺失与输入不匹配异常问题

Hey there, let's work through your Java program issues step by step. You've hit two distinct problems, so we'll tackle each one and fix the code properly.

1. 第一个问题:主方法缺失

你最初遇到的错误是因为主方法放在了独立的Driver类中,但你直接运行了Township类。Java要求被运行的类必须包含public static void main(String[] args)方法(JavaFX应用除外)。你把主方法移到Township类的方向是对的,但这引出了第二个问题。

2. 第二个问题:InputMismatchException

这个异常发生在Scanner试图读取某一类型的值(比如int)但遇到了其他内容(字符串、空行或格式错误)时。我们来拆解问题所在并修复:

问题1:文件读取格式不匹配

你的readFile方法假设bicycledata.txt的格式是这样的:

TownshipName
100
50
AnotherTown
200
150

如果你的文件格式不同(比如每个镇的所有数据在一行),nextLine()和nextInt()的调用就会不同步,导致异常。另外,调用nextInt()后需要正确处理换行符,我们可以通过更安全的方式读取每行内容并解析值。

问题2:用户输入的Scanner同步问题

在getInput方法中,用sc.nextInt()读取家庭数和自行车数后,输入缓冲区中残留的换行符会被下一个sc.nextLine()读取,导致你回到菜单选择选项1时,得到的镇名是空字符串。

修复后的完整代码(带注释说明)

以下是修复了所有问题的代码,注释标注了关键修改点:

import java.util.*;
import java.io.*;

public class Township {
    // 实例变量
    String name;
    int households;
    int bicycles;
    double average;
    String tier;
    double funding;

    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        Township town[] = new Township[10];
        int count = readFile(town);

        while (true) {
            System.out.println("1. Input\n2. Report\n3. Exit");
            System.out.print("Enter choice: ");
            
            // 增加输入校验,确保用户输入整数
            while (!sc.hasNextInt()) {
                System.out.println("Please enter a valid number (1-3)!");
                sc.next(); // 消耗无效输入
            }
            int choice = sc.nextInt();
            sc.nextLine(); // 消耗选择后的换行符

            switch (choice) {
                case 1:
                    town[count] = getInput(sc);
                    count++;
                    break;
                case 2:
                    printReport(town, count);
                    break;
                case 3:
                    writeFile(town, count);
                    System.out.println("Goodbye!");
                    return;
                default:
                    System.out.println("Invalid choice, please pick 1, 2, or 3.");
            }
        }
    }

    // 构造方法
    public Township(String name, int households, int bicycles) {
        this.name = name;
        this.households = households;
        this.bicycles = bicycles;
        // 创建对象时自动计算相关值,避免遗漏调用
        calculateAverageBikes();
        calculateFunding();
        calculateTier();
    }

    // 重命名方法以遵循Java驼峰命名规范
    private void calculateAverageBikes() {
        average = (double) bicycles / households;
    }

    private void calculateFunding() {
        if (average >= 3.0) funding = 50000.00;
        else if (average >= 2.0) funding = 40000.00;
        else if (average >= 1.0) funding = 30000.00;
        else if (average >= 0.5) funding = 20000.00;
        else funding = 0.00;
    }

    private void calculateTier() {
        if (average >= 3.0) tier = "One";
        else if (average >= 2.0) tier = "Two";
        else if (average >= 1.0) tier = "Three";
        else if (average >= 0.5) tier = "Four";
        else tier = "Five";
    }

    // 按镇名字母顺序排序
    public static void sort(Township[] townships, int count) {
        for (int i = 0; i < count - 1; i++) {
            for (int j = i + 1; j < count; j++) {
                if (townships[i].name.compareTo(townships[j].name) > 0) {
                    Township temp = townships[i];
                    townships[i] = townships[j];
                    townships[j] = temp;
                }
            }
        }
    }

    // 向控制台打印报告
    public static void printReport(Township[] townships, int count) {
        sort(townships, count);
        System.out.println("---------------------------------------------------------------------------------------------------");
        System.out.printf("%-20s%-15s%-18s%-20s%-20s%s\n", 
            "Township Name", "Households", "Bicycles Reported", "Average Bikes/Household", "Proposed Funding", "Tier Designation");
        System.out.println("---------------------------------------------------------------------------------------------------");
        for (int i = 0; i < count; i++) {
            System.out.printf("%-20s%-15d%-18d%-20.2f%-20.2f%s\n", 
                townships[i].name, townships[i].households, townships[i].bicycles, 
                townships[i].average, townships[i].funding, townships[i].tier);
        }
    }

    // 安全获取用户输入
    public static Township getInput(Scanner sc) {
        System.out.print("Enter the name of Township: ");
        String name = sc.nextLine();
        
        // 校验家庭数输入
        int households = 0;
        while (true) {
            System.out.print("Enter the number of households: ");
            if (sc.hasNextInt()) {
                households = sc.nextInt();
                if (households > 0) break; // 确保是正数
                else System.out.println("Households must be a positive number!");
            } else {
                System.out.println("Please enter a valid integer for households.");
                sc.next(); // 消耗无效输入
            }
        }

        // 校验自行车数输入
        int bicycles = 0;
        while (true) {
            System.out.print("Enter the number of bicycles reported: ");
            if (sc.hasNextInt()) {
                bicycles = sc.nextInt();
                if (bicycles >= 0) break; // 非负数
                else System.out.println("Bicycles can't be negative!");
            } else {
                System.out.println("Please enter a valid integer for bicycles.");
                sc.next(); // 消耗无效输入
            }
        }
        sc.nextLine(); // 消耗最后一个整数输入后的换行符

        return new Township(name, households, bicycles);
    }

    // 安全读取文件(处理常见格式问题)
    public static int readFile(Township[] townships) throws IOException {
        int count = 0;
        File file = new File("bicycledata.txt");
        
        // 读取前检查文件是否存在
        if (!file.exists()) {
            System.out.println("Warning: bicycledata.txt not found, starting with empty list.");
            return count;
        }

        Scanner fileScanner = new Scanner(file);
        while (fileScanner.hasNextLine() && count < townships.length) {
            String name = fileScanner.nextLine().trim();
            // 跳过文件中的空行
            if (name.isEmpty()) continue;

            // 读取家庭数
            if (!fileScanner.hasNextInt()) {
                System.out.println("Invalid data in file for households, skipping entry: " + name);
                // 跳过该条目剩余的行
                while (fileScanner.hasNextLine()) {
                    if (fileScanner.hasNextInt()) break;
                    fileScanner.nextLine();
                }
                continue;
            }
            int households = fileScanner.nextInt();
            fileScanner.nextLine(); // 消耗换行符

            // 读取自行车数
            if (!fileScanner.hasNextInt()) {
                System.out.println("Invalid data in file for bicycles, skipping entry: " + name);
                while (fileScanner.hasNextLine()) fileScanner.nextLine();
                continue;
            }
            int bicycles = fileScanner.nextInt();
            fileScanner.nextLine(); // 消耗换行符

            if (households > 0 && bicycles >= 0) {
                townships[count] = new Township(name, households, bicycles);
                count++;
            } else {
                System.out.println("Invalid values for " + name + ", skipping (households must be positive, bicycles non-negative).");
            }
        }
        fileScanner.close();
        return count;
    }

    // 写入报告到文件
    public static void writeFile(Township[] townships, int count) throws IOException {
        sort(townships, count);
        // 使用try-with-resources自动关闭写入流
        try (PrintWriter pout = new PrintWriter(new FileWriter("report.txt"))) {
            pout.println("---------------------------------------------------------------------------------------------------");
            pout.printf("%-20s%-15s%-18s%-20s%-20s%s\n", 
                "Township Name", "Households", "Bicycles Reported", "Average Bikes/Household", "Proposed Funding", "Tier Designation");
            pout.println("---------------------------------------------------------------------------------------------------");
            for (int i = 0; i < count; i++) {
                pout.printf("%-20s%-15d%-18d%-20.2f%-20.2f%s\n", 
                    townships[i].name, townships[i].households, townships[i].bicycles, 
                    townships[i].average, townships[i].funding, townships[i].tier);
            }
        }
    }
}

关键修改点:

  • 主方法位置:将主方法保留在public Township类中,确保Java运行时能找到它。
  • 输入校验:为用户和文件输入添加了整数校验,防止InputMismatchException。
  • Scanner同步:修复了nextInt()后的换行符处理问题,避免镇名输入为空。
  • 文件读取鲁棒性:增加了文件存在性检查、空行跳过,遇到无效数据时优雅处理而非崩溃。
  • Java命名规范:将AverageBikes()这类方法重命名为calculateAverageBikes(),遵循驼峰命名法。
  • 自动计算:将平均值、资金、等级计算移到构造方法中,确保创建对象时自动执行,避免遗漏调用。
  • 资源自动管理:使用try-with-resources处理文件写入,确保流能正确关闭。

bicycledata.txt要求的格式:

确保你的输入文件采用以下结构(每个镇占3行):

Springfield
200
450
Shelbyville
150
300

如果你偏好其他格式(比如每行逗号分隔数据),可以告诉我,我们再调整readFile方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 15:12:45