|
|
|
|
@ -40,9 +40,6 @@ public class MathQuestionGenerator {
|
|
|
|
|
private static User currentUser = null;
|
|
|
|
|
private static final Scanner scanner = new Scanner(System.in, java.nio.charset.StandardCharsets.UTF_8);
|
|
|
|
|
|
|
|
|
|
// 【人工修改】添加程序退出时的资源清理
|
|
|
|
|
// 修改前:Scanner资源没有正确关闭,可能导致资源泄漏
|
|
|
|
|
// 修改后:添加shutdown hook确保Scanner资源正确关闭
|
|
|
|
|
static {
|
|
|
|
|
Runtime.getRuntime().addShutdownHook(new Thread(scanner::close));
|
|
|
|
|
}
|
|
|
|
|
@ -88,9 +85,6 @@ public class MathQuestionGenerator {
|
|
|
|
|
public static void main(String[] args) {
|
|
|
|
|
showWelcomeMessage();
|
|
|
|
|
|
|
|
|
|
// 【人工修复】修复while循环警告,简化循环逻辑
|
|
|
|
|
// 修改前:使用shouldContinue变量但设置后立即break,IDEA提示条件始终为true
|
|
|
|
|
// 修改后:直接使用while(true)配合break,逻辑更简洁清晰
|
|
|
|
|
while (true) {
|
|
|
|
|
Boolean loginResult = login();
|
|
|
|
|
if (loginResult == null) {
|
|
|
|
|
@ -124,7 +118,8 @@ public class MathQuestionGenerator {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 用户登录验证
|
|
|
|
|
* @return 登录是否成功,null表示用户选择退出
|
|
|
|
|
* @return 登录结果:true表示成功,false表示失败,null表示用户选择退出
|
|
|
|
|
* 注意:返回null是设计需要,用于区分退出和失败
|
|
|
|
|
*/
|
|
|
|
|
private static Boolean login() {
|
|
|
|
|
System.out.println("=== 用户登录 ===");
|
|
|
|
|
@ -269,12 +264,11 @@ public class MathQuestionGenerator {
|
|
|
|
|
*/
|
|
|
|
|
private static void waitForEnter() {
|
|
|
|
|
try {
|
|
|
|
|
// 【人工修复】修复InputStream.read()结果被忽略的警告
|
|
|
|
|
// 修改前:System.in.read()的结果被忽略,IDEA显示警告
|
|
|
|
|
// 修改后:将读取结果赋值给变量,消除警告
|
|
|
|
|
// 等待用户按回车键
|
|
|
|
|
@SuppressWarnings("unused")
|
|
|
|
|
int result = System.in.read();
|
|
|
|
|
// 等待用户按回车键,读取直到遇到换行符
|
|
|
|
|
int ch;
|
|
|
|
|
while ((ch = System.in.read()) != -1 && ch != '\n') {
|
|
|
|
|
// 继续读取直到遇到换行符
|
|
|
|
|
}
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
// 忽略读取错误
|
|
|
|
|
}
|
|
|
|
|
@ -314,9 +308,6 @@ public class MathQuestionGenerator {
|
|
|
|
|
* @return 切换是否成功
|
|
|
|
|
*/
|
|
|
|
|
private static boolean handleSwitchCommand(String command) {
|
|
|
|
|
// 【人工修复】修复字符串越界风险,添加长度检查
|
|
|
|
|
// 修改前:command.substring(3) 可能抛出StringIndexOutOfBoundsException
|
|
|
|
|
// 修改后:先检查命令长度,确保安全访问
|
|
|
|
|
if (command.length() < 3) {
|
|
|
|
|
System.out.println();
|
|
|
|
|
System.out.println("✗ 请输入小学、初中和高中三个选项中的一个");
|
|
|
|
|
@ -326,20 +317,12 @@ public class MathQuestionGenerator {
|
|
|
|
|
String targetGrade = command.substring(3).trim();
|
|
|
|
|
|
|
|
|
|
if (targetGrade.equals("小学") || targetGrade.equals("初中") || targetGrade.equals("高中")) {
|
|
|
|
|
// 【人工修复】修复currentUser为null时的NullPointerException
|
|
|
|
|
// 修改前:当currentUser为null时,调用currentUser.username()和currentUser.password()会抛出异常
|
|
|
|
|
// 修改后:先检查currentUser是否为null,如果为null则直接返回false
|
|
|
|
|
if (currentUser == null) {
|
|
|
|
|
System.out.println();
|
|
|
|
|
System.out.println("✗ 用户未登录,无法切换年级");
|
|
|
|
|
System.out.println("按回车键继续...");
|
|
|
|
|
System.out.flush();
|
|
|
|
|
try {
|
|
|
|
|
@SuppressWarnings("unused")
|
|
|
|
|
int readResult = System.in.read();
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
// 忽略读取错误
|
|
|
|
|
}
|
|
|
|
|
waitForEnter();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
currentUser = new User(currentUser.username(), currentUser.password(), targetGrade);
|
|
|
|
|
@ -350,19 +333,7 @@ public class MathQuestionGenerator {
|
|
|
|
|
// 修改后:切换成功后要求按回车键,让用户有时间阅读信息,界面切换更自然
|
|
|
|
|
System.out.println("按回车键继续...");
|
|
|
|
|
System.out.flush();
|
|
|
|
|
try {
|
|
|
|
|
// 【人工修复】修复InputStream.read()结果被忽略的警告
|
|
|
|
|
// 修改前:System.in.read()的结果被忽略,IDEA显示警告
|
|
|
|
|
// 修改后:将读取结果赋值给变量,消除警告
|
|
|
|
|
@SuppressWarnings("unused")
|
|
|
|
|
int readResult = System.in.read();
|
|
|
|
|
// 【人工修复】修复空if语句体警告
|
|
|
|
|
// 修改前:if (readResult == -1) { } 空语句体,IDEA显示警告
|
|
|
|
|
// 修改后:删除空的if语句,因为IOException已经被catch块处理
|
|
|
|
|
// readResult用于等待用户按回车键,不需要检查具体值
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
// 忽略读取错误
|
|
|
|
|
}
|
|
|
|
|
waitForEnter();
|
|
|
|
|
return true;
|
|
|
|
|
} else {
|
|
|
|
|
System.out.println();
|
|
|
|
|
@ -372,19 +343,7 @@ public class MathQuestionGenerator {
|
|
|
|
|
// 修改后:切换失败后要求按回车键,让用户有时间阅读错误信息,界面切换更自然
|
|
|
|
|
System.out.println("按回车键继续...");
|
|
|
|
|
System.out.flush();
|
|
|
|
|
try {
|
|
|
|
|
// 【人工修复】修复InputStream.read()结果被忽略的警告
|
|
|
|
|
// 修改前:System.in.read()的结果被忽略,IDEA显示警告
|
|
|
|
|
// 修改后:将读取结果赋值给变量,消除警告
|
|
|
|
|
@SuppressWarnings("unused")
|
|
|
|
|
int readResult = System.in.read();
|
|
|
|
|
// 【人工修复】修复空if语句体警告
|
|
|
|
|
// 修改前:if (readResult == -1) { } 空语句体,IDEA显示警告
|
|
|
|
|
// 修改后:删除空的if语句,因为IOException已经被catch块处理
|
|
|
|
|
// readResult用于等待用户按回车键,不需要检查具体值
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
// 忽略读取错误
|
|
|
|
|
}
|
|
|
|
|
waitForEnter();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -409,18 +368,12 @@ public class MathQuestionGenerator {
|
|
|
|
|
// 【人工修改】创建paper文件夹结构:paper->用户名->年级
|
|
|
|
|
// 修改前:File userDir = new File(currentUser.getUsername());
|
|
|
|
|
// 修改后:创建三级文件夹结构,试卷集中管理
|
|
|
|
|
// 【人工修复】修复currentUser为null时的NullPointerException
|
|
|
|
|
// 修改前:当currentUser为null时,调用currentUser.username()会抛出异常
|
|
|
|
|
// 修改后:先检查currentUser是否为null,如果为null则抛出异常
|
|
|
|
|
if (currentUser == null) {
|
|
|
|
|
throw new IllegalStateException("用户未登录,无法创建文件夹");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
File paperDir = new File("paper");
|
|
|
|
|
if (!paperDir.exists()) {
|
|
|
|
|
// 【人工修复】修复File.mkdir()结果被忽略的警告
|
|
|
|
|
// 修改前:paperDir.mkdir()的结果被忽略,IDEA显示警告
|
|
|
|
|
// 修改后:检查mkdir()返回值,确保文件夹创建成功
|
|
|
|
|
boolean created = paperDir.mkdir();
|
|
|
|
|
if (!created) {
|
|
|
|
|
System.err.println("警告:无法创建paper文件夹");
|
|
|
|
|
@ -429,9 +382,6 @@ public class MathQuestionGenerator {
|
|
|
|
|
|
|
|
|
|
File userDir = new File(paperDir, currentUser.username());
|
|
|
|
|
if (!userDir.exists()) {
|
|
|
|
|
// 【人工修复】修复File.mkdir()结果被忽略的警告
|
|
|
|
|
// 修改前:userDir.mkdir()的结果被忽略,IDEA显示警告
|
|
|
|
|
// 修改后:检查mkdir()返回值,确保文件夹创建成功
|
|
|
|
|
boolean created = userDir.mkdir();
|
|
|
|
|
if (!created) {
|
|
|
|
|
System.err.println("警告:无法创建用户文件夹:" + currentUser.username());
|
|
|
|
|
@ -447,9 +397,6 @@ public class MathQuestionGenerator {
|
|
|
|
|
|
|
|
|
|
for (File gradeDir : gradeDirs) {
|
|
|
|
|
if (!gradeDir.exists()) {
|
|
|
|
|
// 【人工修复】修复File.mkdir()结果被忽略的警告
|
|
|
|
|
// 修改前:gradeDir.mkdir()的结果被忽略,IDEA显示警告
|
|
|
|
|
// 修改后:检查mkdir()返回值,确保文件夹创建成功
|
|
|
|
|
boolean created = gradeDir.mkdir();
|
|
|
|
|
if (!created) {
|
|
|
|
|
System.err.println("警告:无法创建年级文件夹:" + gradeDir.getName());
|
|
|
|
|
@ -496,9 +443,6 @@ public class MathQuestionGenerator {
|
|
|
|
|
int attempts = 0;
|
|
|
|
|
|
|
|
|
|
do {
|
|
|
|
|
// 【人工修改】根据年级设置不同的最少操作数
|
|
|
|
|
// 修改前:int operandCount = random.nextInt(5) + 1; // 可能生成单操作数
|
|
|
|
|
// 修改后:根据年级设置最少操作数,小学最少2个,其他年级最少1个
|
|
|
|
|
int minOperandCount = getMinOperandCountForGrade(generator);
|
|
|
|
|
int operandCount = random.nextInt(MAX_OPERAND_COUNT - minOperandCount + 1) + minOperandCount;
|
|
|
|
|
int[] operands = new int[operandCount];
|
|
|
|
|
@ -539,10 +483,6 @@ public class MathQuestionGenerator {
|
|
|
|
|
private static Set<String> loadHistoryQuestions(File userDir) {
|
|
|
|
|
Set<String> historyQuestions = new HashSet<>();
|
|
|
|
|
|
|
|
|
|
// 【人工修改】从对应的年级文件夹加载历史题目
|
|
|
|
|
// 【人工修复】修复currentUser为null时的NullPointerException
|
|
|
|
|
// 修改前:当currentUser为null时,调用currentUser.grade()会抛出异常
|
|
|
|
|
// 修改后:先检查currentUser是否为null,如果为null则抛出异常
|
|
|
|
|
if (currentUser == null) {
|
|
|
|
|
throw new IllegalStateException("用户未登录,无法加载历史题目");
|
|
|
|
|
}
|
|
|
|
|
@ -560,9 +500,6 @@ public class MathQuestionGenerator {
|
|
|
|
|
String line;
|
|
|
|
|
while ((line = reader.readLine()) != null) {
|
|
|
|
|
if (line.matches("\\d+\\.\\s+.+")) {
|
|
|
|
|
// 【人工修复】修复字符串越界风险,添加安全检查
|
|
|
|
|
// 修改前:line.indexOf(".") 可能返回-1,导致substring(-1+1)问题
|
|
|
|
|
// 修改后:先检查indexOf结果,确保安全访问
|
|
|
|
|
int dotIndex = line.indexOf(".");
|
|
|
|
|
if (dotIndex != -1 && dotIndex + 1 < line.length()) {
|
|
|
|
|
String question = line.substring(dotIndex + 1).trim();
|
|
|
|
|
@ -598,10 +535,6 @@ public class MathQuestionGenerator {
|
|
|
|
|
* @return 输出文件
|
|
|
|
|
*/
|
|
|
|
|
private static File createOutputFile(File userDir) {
|
|
|
|
|
// 【人工修改】将文件保存到对应的年级文件夹
|
|
|
|
|
// 【人工修复】修复currentUser为null时的NullPointerException
|
|
|
|
|
// 修改前:当currentUser为null时,调用currentUser.grade()会抛出异常
|
|
|
|
|
// 修改后:先检查currentUser是否为null,如果为null则抛出异常
|
|
|
|
|
if (currentUser == null) {
|
|
|
|
|
throw new IllegalStateException("用户未登录,无法创建输出文件");
|
|
|
|
|
}
|
|
|
|
|
@ -647,24 +580,12 @@ public class MathQuestionGenerator {
|
|
|
|
|
// 修改后:生成题目后要求按回车键,让用户有时间阅读生成结果,界面切换更自然
|
|
|
|
|
System.out.println("按回车键继续...");
|
|
|
|
|
System.out.flush();
|
|
|
|
|
try {
|
|
|
|
|
// 【人工修复】修复InputStream.read()结果被忽略的警告
|
|
|
|
|
// 修改前:System.in.read()的结果被忽略,IDEA显示警告
|
|
|
|
|
// 修改后:将读取结果赋值给变量,消除警告
|
|
|
|
|
// 等待用户按回车键
|
|
|
|
|
@SuppressWarnings("unused")
|
|
|
|
|
int result = System.in.read();
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
// 忽略读取错误
|
|
|
|
|
}
|
|
|
|
|
waitForEnter();
|
|
|
|
|
System.out.println();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 用户类,存储用户信息
|
|
|
|
|
* 【人工修复】将User类改为记录类,消除IDEA警告
|
|
|
|
|
* 修改前:使用传统类定义,IDEA提示"类可以是记录类"
|
|
|
|
|
* 修改后:使用Java 14+的记录类语法,代码更简洁
|
|
|
|
|
*/
|
|
|
|
|
record User(String username, String password, String grade) {
|
|
|
|
|
// 记录类自动生成构造函数、getter方法、equals、hashCode和toString
|
|
|
|
|
|