#include <stdio.h>
#include <string.h>
#include <math.h>
// 定义学生结构体
struct Student {
char id[20]; // 学号
char className[20]; // 班级
char name[20]; // 姓名
int startHour; // 上机开始时间(小时)
int startMinute; // 上机开始时间(分钟)
int endHour; // 下机时间(小时)
int endMinute; // 下机时间(分钟)
int isOnline; // 是否在线
double cost; // 费用
};
// 全局变量
struct Student students[30];
int studentCount = 0;
const int MAX_STUDENTS = 30;
// 函数声明
void inputStudent();
void calculateCost(int index);
void searchStudent();
void displayComputerStatus();
double calculateTimeDifference(int startH, int startM, int endH, int endM);
void showMenu();
void saveToFile();
void loadFromFile();
void saveStudentInfo(const char* filename);
void loadStudentInfo(const char* filename);
void saveComputerLog(const char* filename);
void loadComputerLog(const char* filename);
void initializeDefaultStudents();
// 定义文件名常量
#define STUDENT_FILE "student_info.txt"
#define COMPUTER_LOG "computer_log.txt"
int main() {
loadFromFile(); // 程序启动时加载数据
int choice;
while (1) {
showMenu();
printf("请输入您的选择: ");
scanf("%d", &choice);
switch (choice) {
case 1:
inputStudent();
saveToFile(); // 添加学生后保存
break;
case 2: {
int index;
printf("请输入要结算的学生序号(0-%d): ", studentCount-1);
scanf("%d", &index);
calculateCost(index);
saveToFile(); // 计算费用后保存
break;
}
case 3:
searchStudent();
break;
case 4:
displayComputerStatus();
break;
case 0:
saveToFile(); // 退出前保存
printf("程序已退出!\n");
return 0;
default:
printf("无效选择,请重试!\n");
}
}
return 0;
}
void showMenu() {
printf("\n====== 机房收费管理系统 ======\n");
printf("1. 输入学生信息\n");
printf("2. 计算上机费用\n");
printf("3. 查询学生信息\n");
printf("4. 显示机器使用情况\n");
printf("0. 退出系统\n");
printf("===========================\n");
}
void inputStudent() {
if (studentCount >= MAX_STUDENTS) {
printf("已达到最大学生数量!\n");
return;
}
printf("请输入学生信息:\n");
printf("学号: ");
scanf("%s", students[studentCount].id);
printf("班级: ");
scanf("%s", students[studentCount].className);
printf("姓名: ");
scanf("%s", students[studentCount].name);
printf("上机时间(时 分): ");
scanf("%d %d", &students[studentCount].startHour,
&students[studentCount].startMinute);
students[studentCount].isOnline = 1;
students[studentCount].cost = 0;
studentCount++;
printf("学生信息录入成功!\n");
}
void calculateCost(int index) {
if (index < 0 || index >= studentCount) {
printf("无效的学生序号!\n");
return;
}
if (!students[index].isOnline) {
printf("该学生已经下机!\n");
return;
}
printf("请输入下机时间(时 分): ");
scanf("%d %d", &students[index].endHour, &students[index].endMinute);
double hours = calculateTimeDifference(
students[index].startHour,
students[index].startMinute,
students[index].endHour,
students[index].endMinute
);
students[index].cost = ceil(hours) * 1.0;
students[index].isOnline = 0;
printf("费用计算完成!\n");
printf("学生: %s\n", students[index].name);
printf("上机时间: %.2f小时\n", hours);
printf("费用: %.2f元\n", students[index].cost);
}
double calculateTimeDifference(int startH, int startM, int endH, int endM) {
int totalMinutes = (endH * 60 + endM) - (startH * 60 + startM);
return totalMinutes / 60.0;
}
void searchStudent() {
printf("\n查询方式:\n");
printf("1. 按班级查询\n");
printf("2. 按学号查询\n");
printf("3. 按姓名查询\n");
int choice;
char searchTerm[20];
printf("请选择查询方式: ");
scanf("%d", &choice);
printf("请输入查询关键字: ");
scanf("%s", searchTerm);
printf("\n查询结果:\n");
printf("%-10s%-10s%-10s%-15s%-15s\n",
"学号", "班级", "姓名", "状态", "上机时间");
for (int i = 0; i < studentCount; i++) {
int match = 0;
switch (choice) {
case 1:
match = (strcmp(students[i].className, searchTerm) == 0);
break;
case 2:
match = (strcmp(students[i].id, searchTerm) == 0);
break;
case 3:
match = (strcmp(students[i].name, searchTerm) == 0);
break;
}
if (match) {
printf("%-10s%-10s%-10s%-15s%02d:%02d\n",
students[i].id,
students[i].className,
students[i].name,
students[i].isOnline ? "在线" : "已下机",
students[i].startHour,
students[i].startMinute);
}
}
}
void displayComputerStatus() {
int online = 0;
int offline = 0;
for (int i = 0; i < studentCount; i++) {
if (students[i].isOnline) {
online++;
} else {
offline++;
}
}
printf("\n机器使用情况统计:\n");
printf("总学生数:%d\n", studentCount);
printf("当前在线:%d\n", online);
printf("已经下机:%d\n", offline);
printf("\n使用情况图示:\n");
printf("在线学生: ");
for (int i = 0; i < online; i++) {
printf("█");
}
printf(" (%d)\n", online);
printf("离线学生: ");
for (int i = 0; i < offline; i++) {
printf("█");
}
printf(" (%d)\n", offline);
}
// 添加保存到文件的函数
void saveToFile() {
// 保存学生基本信息
saveStudentInfo(STUDENT_FILE);
// 保存上机记录
saveComputerLog(COMPUTER_LOG);
}
// 添加从文件加载的函数
void loadFromFile() {
FILE *fp = fopen(STUDENT_FILE, "r");
if (fp == NULL) {
printf("首次运行,初始化30名学生信息...\n");
initializeDefaultStudents();
saveToFile(); // 保存初始化的数据
return;
}
fclose(fp);
// 加载学生基本信息
loadStudentInfo(STUDENT_FILE);
// 加载上机记录
loadComputerLog(COMPUTER_LOG);
}
// 保存学生基本信息(文本格式)
void saveStudentInfo(const char* filename) {
FILE *fp = fopen(filename, "w");
if (fp == NULL) {
printf("无法打开文件 %s!\n", filename);
return;
}
fprintf(fp, "学生总数: %d\n", studentCount);
fprintf(fp, "学号\t班级\t姓名\t状态\t费用\n");
for (int i = 0; i < studentCount; i++) {
fprintf(fp, "%s\t%s\t%s\t%s\t%.2f\n",
students[i].id,
students[i].className,
students[i].name,
students[i].isOnline ? "在线" : "离线",
students[i].cost);
}
fclose(fp);
printf("学生基本信息已保存到 %s\n", filename);
}
// 加载学生基本信息(文本格式)
void loadStudentInfo(const char* filename) {
FILE *fp = fopen(filename, "r");
if (fp == NULL) {
printf("未找到文件 %s,将创建新文件。\n", filename);
return;
}
char line[256];
// 跳过前两行(标题行)
fgets(line, sizeof(line), fp);
fgets(line, sizeof(line), fp);
studentCount = 0;
while (fscanf(fp, "%s\t%s\t%s\t%s\t%lf\n",
students[studentCount].id,
students[studentCount].className,
students[studentCount].name,
line, // 临时存储状态
&students[studentCount].cost) == 5) {
students[studentCount].isOnline = (strcmp(line, "在线") == 0);
studentCount++;
if (studentCount >= MAX_STUDENTS) break;
}
fclose(fp);
printf("已从 %s 加载 %d 条学生记录\n", filename, studentCount);
}
// 保存上机记录(文本格式)
void saveComputerLog(const char* filename) {
FILE *fp = fopen(filename, "w");
if (fp == NULL) {
printf("无法打开文件 %s!\n", filename);
return;
}
fprintf(fp, "上机记录\n");
fprintf(fp, "学号\t开始时间\t结束时间\t费用\n");
for (int i = 0; i < studentCount; i++) {
fprintf(fp, "%s\t%02d:%02d\t",
students[i].id,
students[i].startHour,
students[i].startMinute);
if (!students[i].isOnline) {
fprintf(fp, "%02d:%02d\t%.2f\n",
students[i].endHour,
students[i].endMinute,
students[i].cost);
} else {
fprintf(fp, "在线中\t0.00\n");
}
}
fclose(fp);
printf("上机记录已保存到 %s\n", filename);
}
// 加载上机记录(文本格式)
void loadComputerLog(const char* filename) {
FILE *fp = fopen(filename, "r");
if (fp == NULL) {
printf("未找到文件 %s,将创建新文件。\n", filename);
return;
}
char line[256];
// 跳过前两行(标题行)
fgets(line, sizeof(line), fp);
fgets(line, sizeof(line), fp);
for (int i = 0; i < studentCount; i++) {
char status[20];
fscanf(fp, "%*s\t%d:%d\t%s",
&students[i].startHour,
&students[i].startMinute,
status);
if (strcmp(status, "在线中") == 0) {
students[i].isOnline = 1;
fscanf(fp, "%*f\n");
} else {
students[i].isOnline = 0;
fscanf(fp, "%d:%d\t%lf\n",
&students[i].endHour,
&students[i].endMinute,
&students[i].cost);
}
}
fclose(fp);
printf("已从 %s 加载上机记录\n", filename);
}
// 添加初始化学生信息的函数
void initializeDefaultStudents() {
// 预设的班级列表
const char* classes[] = {"计算机1班", "计算机2班", "软件1班", "软件2班", "网络1班"};
studentCount = 30; // 设置为30名学生
for (int i = 0; i < studentCount; i++) {
// 生成学号 (例如: 2024001, 2024002, ...)
sprintf(students[i].id, "2024%03d", i + 1);
// 分配班级 (循环使用预设的班级)
strcpy(students[i].className, classes[i % 5]);
// 生成姓名 (例如: 学生1, 学生2, ...)
sprintf(students[i].name, "学生%d", i + 1);
// 设置上机时间 (8:00 到 17:00 之间随机分配)
students[i].startHour = 8 + (i % 10); // 8:00 到 17:00
students[i].startMinute = (i * 2) % 60; // 0到58的偶数分钟
// 初始状态都设为在线
students[i].isOnline = 1;
students[i].cost = 0.0;
}
printf("已初始化30名学生信息。\n");
// 显示初始化的学生信息
printf("\n初始化的学生信息如下:\n");
printf("%-10s%-15s%-10s%-15s\n", "学号", "班级", "姓名", "上机时间");
printf("----------------------------------------\n");
for (int i = 0; i < studentCount; i++) {
printf("%-10s%-15s%-10s%02d:%02d\n",
students[i].id,
students[i].className,
students[i].name,
students[i].startHour,
students[i].startMinute);
}
printf("----------------------------------------\n");
}