Java 学生成绩管理系统:控制台输入与文件输出完整实现
一、题目代码分析
以下是需要补全的Java代码,核心功能是通过控制台输入5名学生的学号、姓名及3门课程成绩,计算总成绩后将学生信息(含平均分)写入文件。代码分为input()
(输入)、output()
(输出)两个核心方法,需补全关键逻辑以实现完整功能:
import java.io.*;
public class Java_2{
// 存储学生信息的数组:学号、姓名、3门成绩、总成绩
String[] number = new String[5];
String[] name = new String[5];
int[][] grade = new int[5][3];
float[] sum = new float[5];
public static void main(String[] args) throws Exception{
Java_2 student = new Java_2();
student.input(); // 调用输入方法
//**********Found**********
student.________(); // 调用输出方法
}
// 从控制台输入学生信息
void input( ) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try{
for(int i=0;i<5;i++){
System.out.println("请输入学生学号:");
number[i] = br.readLine();
//**********Found**********
System.out.println("请输入第"+_______+"名学生姓名及三门课成绩:");
name[i] = br.readLine();
// 输入3门课程成绩
for(int j=0;j<3;j++){
grade[i][j] = Integer.parseInt( br.readLine() );
}
System.out.println();
// 计算该学生总成绩
sum[i] = grade[i][0] + grade[i][1] + grade[i][2];
}
}catch(NumberFormatException e){
System.out.println("输入数据有误!");
}
}
// 将学生信息写入文件
void output( )throws IOException{
//**********Found**********
FileWriter fw = new FileWriter("_____________"); // 创建文件输出流
BufferedWriter bw = new BufferedWriter(fw);
// 写入文件表头
bw.write("No. "+"name "+"grade 1 "+"grade 2 "+"grade 3 "+"average ");
bw.newLine(); // 换行
// 循环写入5名学生信息
for(int i=0;i<5;i++){
bw.write(number[i]); // 写入学号
//**********Found**********
bw.write(" "+ ___________); // 写入姓名
// 写入3门成绩
for(int j=0;j<3;j++)
bw.write(" "+grade[i][j]);
//**********Found**********
bw.write(" "+sum[i]/___________); // 计算并写入平均分
bw.newLine(); // 换行
}
//**********Found**********
bw.__________(); // 关闭缓冲流
}
}
二、空白处逐一解析
要实现“输入→计算→输出”的完整流程,需围绕“方法调用”“用户提示”“文件操作”“数据计算”四个核心目标,逐个突破空白:
1. 第一个空白:student.________();
- 解析:
main
方法中已调用input()
完成输入,需调用output()
方法将数据写入文件(代码中已定义output()
方法)。 - 答案:
output
2. 第二个空白:System.out.println("请输入第"+_______+"名学生姓名及三门课成绩:");
- 解析:循环变量
i
从0开始(i=0
对应第1名学生),需将i
转换为“第N名”的自然计数(i+1
),提升用户体验。 - 答案:
(i+1)
3. 第三个空白:FileWriter fw = new FileWriter("_____________");
- 解析:
FileWriter
需指定输出文件路径及名称,题目未指定路径,默认写入当前项目根目录,文件名建议为student_grades.txt
(清晰表达文件用途)。 - 答案:
student_grades.txt
4. 第四个空白:bw.write(" "+ ___________);
- 解析:循环中已写入学号(
number[i]
),接下来需写入对应学生的姓名,姓名存储在name[i]
数组中。 - 答案:
name[i]
5. 第五个空白:bw.write(" "+sum[i]/___________);
- 解析:
sum[i]
是该学生3门课程的总成绩,平均分 = 总成绩 ÷ 课程数(3门),因此除数为3
。 - 答案:
3
6. 第六个空白:bw.__________();
- 解析:
BufferedWriter
是缓冲流,使用后必须关闭以释放资源(确保数据全部写入文件,避免数据丢失),关闭方法为close()
。 - 答案:
close
三、完整正确代码
优化说明:
- 增加
finally
块确保流关闭,避免资源泄漏;- 使用
String.format()
格式化输出,确保文件内容对齐(如%-6s
表示左对齐占6字符);- 优化用户提示信息,明确输入步骤;
- 保留平均分2位小数,提升数据可读性。
四、代码运行示例
1. 控制台输入流程
请输入第1名学生学号:
2024001
请输入第1名学生姓名:
张三
请输入第1名学生的3门课程成绩(每行1个):
85
92
78
第1名学生信息录入完成!
请输入第2名学生学号:
2024002
请输入第2名学生姓名:
李四
请输入第2名学生的3门课程成绩(每行1个):
90
88
95
第2名学生信息录入完成!
...(后续3名学生输入流程类似)
学生信息已成功写入 student_grades.txt 文件!
2. 输出文件(student_grades.txt)内容
No. name grade 1 grade 2 grade 3 average
2024001 张三 85 92 78 85.00
2024002 李四 90 88 95 91.00
2024003 王五 76 80 82 79.33
2024004 赵六 95 93 89 92.33
2024005 钱七 68 72 65 68.33
五、核心知识点总结
通过这个学生成绩管理实例,可系统掌握Java IO流操作、数组应用、异常处理三大核心技术:
1. Java IO流:控制台输入与文件输出
本例使用字符流处理文本数据(学号、姓名、成绩均为文本/整数转文本),核心流对象如下:
流对象 | 作用 | 关键方法 |
---|---|---|
BufferedReader | 高效读取控制台输入(包装InputStreamReader ) | readLine() (读取整行)、close() |
FileWriter | 写入字符到文件 | write(String) 、close() |
BufferedWriter | 缓冲写入(提升效率,减少磁盘IO) | write(String) 、newLine() 、close() |
流操作注意事项:
- 关闭顺序:先关外层流(
BufferedWriter
),再关内层流(FileWriter
); - 资源释放:必须在
finally
块或使用try-with-resources
关闭流,避免资源泄漏; - 异常处理:IO操作必须捕获或声明
IOException
(编译时异常)。
2. 多维数组与数据存储
本例使用数组存储5名学生的结构化信息,体现了数组的“批量数据管理”能力:
- 一维数组:
number[]
(学号)、name[]
(姓名)、sum[]
(总成绩); - 二维数组:
grade[][]
(grade[i][j]
表示第i
名学生的第j
门成绩); - 数组优势:固定大小、索引访问(效率高)、适合存储同类型批量数据。
3. 异常处理:增强程序健壮性
本例处理了两种常见异常,避免程序崩溃:
NumberFormatException
:
当成绩输入非整数(如“abc”)时,Integer.parseInt()
抛出此异常,提示用户“输入数据有误”。IOException
:
IO操作(如文件不存在、权限不足、流未关闭)可能抛出此异常,通过throws
声明由调用者处理(main
方法声明throws Exception
)。
优化建议:
生产环境中可使用try-with-resources
自动关闭流(无需手动写finally
):
// try-with-resources:流会自动关闭(支持实现AutoCloseable接口的类)
try(BufferedWriter bw = new BufferedWriter(new FileWriter("student_grades.txt"))) {
// 写入逻辑
bw.write("表头...");
} catch(IOException e) {
e.printStackTrace();
}
六、拓展与优化建议
本例是基础成绩管理系统,可从以下方向扩展功能,提升实用性:
1. 增加成绩排序功能
按平均分降序排序学生信息,便于查看排名:
// 冒泡排序:按平均分降序排列
public void sortByAverage() {
for(int i=0; i<4; i++) {
for(int j=0; j<4-i; j++) {
float avgJ = sum[j]/3;
float avgJ1 = sum[j+1]/3;
if(avgJ < avgJ1) {
// 交换学号
String tempNum = number[j];
number[j] = number[j+1];
number[j+1] = tempNum;
// 交换姓名、成绩、总成绩(同理)
// ...
}
}
}
}
2. 支持文件读取与修改
增加readFromFile()
方法,从已有的成绩文件中读取数据,支持修改后重新写入:
// 从文件读取学生信息
public void readFromFile() throws IOException {
try(BufferedReader br = new BufferedReader(new FileReader("student_grades.txt"))) {
String line;
int lineCount = 0;
while((line = br.readLine()) != null) {
if(lineCount == 0) {
lineCount++;
continue; // 跳过表头
}
// 分割行数据(按空格分割)
String[] parts = line.trim().split("\\s+");
number[lineCount-1] = parts[0];
name[lineCount-1] = parts[1];
// 解析成绩(parts[2]~parts[4])
for(int j=0; j<3; j++) {
grade[lineCount-1][j] = Integer.parseInt(parts[j+2]);
}
// 计算总成绩
sum[lineCount-1] = grade[lineCount-1][0] + grade[lineCount-1][1] + grade[lineCount-1][2];
lineCount++;
}
}
}
3. 图形化界面(Swing)
用Swing替换控制台输入,提供可视化表单(如文本框、按钮、表格),提升用户体验:
- 使用
JFrame
创建窗口; - 使用
JTable
显示学生信息; - 使用
JButton
绑定“录入”“保存”“排序”功能。
七、总结
本例通过“控制台输入→数据存储→文件输出”的完整流程,展示了Java的IO流操作、数组应用和异常处理能力。这类“数据管理+文件持久化”的场景在实际开发中非常常见(如日志记录、配置保存、数据备份),掌握这些基础技能是编写实用Java程序的关键。
同时,代码的优化过程(如格式化输出、资源自动关闭、异常友好提示)也体现了“健壮性”“可读性”“可维护性”的编程原则,这些原则在大型项目开发中尤为重要。