C语言编写课程管理系统
着急交作业的同学可以直接跳跃到 5 完整代码块
帮别人写的小组作业,for循环不会的大一新生也能完成作业!
1 需求分析
课程管理系统
某校对所开设课程进行管理,每门课程有:课程编号,课程名称,课程性质(公共课、必修课、选修课),总学时,授课学时,实验学时,学分,开课学期等信息。
试设计一课程管理系统,使之能提供以下功能:
(1)系统以菜单方式工作;
(2)课程信息录入功能;
(3)课程信息浏览功能;
(4)课程信息查询功能:
- 提供两种不同的查询方式:
- 按学分查询
- 按课程性质查询;
(5)将满足某种条件的课程停开并将其删除
- 按照课程编号删除
- 课程名称删除;
(6)按照开课学期进行排序(可用典型的冒泡排序);
可适当增加或删除功能
大一C语言小组作业的一道选题
结合需求,分析所学习的知识:
结构体 函数 指针 文件操作
编译环境:VS2019
使用C语言基础语法(链表前的知识)完成,不需要数据结构(这就是另一门课了)的知识
2 需要查的知识点
1 课程的数据结构全部设置为char类型。在后续编写程序%s
,不会那么容易写错。
2 strcmp函数是C语言中的字符串比较函数,用于比较两个字符串的大小。
3 课本上文件流操作的知识点
4 删除课程使用的C语言rename()函数:重命名文件或目录。使用临时文件temp.txt
使逻辑缜密
5 对字符串冒泡排序,使用atoi():int atoi(const char *str );功能:把字符串转换成整型数。str:要进行转换的字符串
3 数据结构和基础函数功能
3.1 课程数据结构
每门课程有:课程编号,课程名称,课程性质(公共课、必修课、选修课),总学时,授课学时,实验学时,学分,开课学期等信息。
// 定义课程结构体
// 为了测试方便,都设置char类型
struct Course{
char number[20]; // 课程编号
char name[50]; // 课程名称
char type[10]; // 课程性质(如必修、选修)
char totalHours[20]; // 总学时
char experimentHours[20]; // 实验学时
char lectureHours[20]; // 授课学时
char credits[10]; // 学分
char semester[20]; // 开课学期,开课学期中大一上为1,大一下为2,大二上为3依次递推
};
3.2 菜单和选择项
// 打印主菜单函数
void PrintMenu()
{
printf(" *****课程管理系统***** \n");
// 打印系统名称
printf("* 1.录入课程信息 *\n");
// 选项1:录入课程信息
printf("* 2.课程信息浏览 *\n");
// 选项2:浏览课程信息
printf("* 3.课程信息查询 *\n");
// 选项3:查询课程信息
printf("* 4.课程信息修改 *\n");
// 选项4:修改课程信息
printf("* 5.删除课程信息 *\n");
// 选项5:删除课程信息
printf("* 6.课程信息排序 *\n");
// 选项6:对课程信息进行排序
printf("* 0.退出课程系统 *\n");
// 选项0:退出系统
printf("请选择操作:\n");
// 提示用户选择操作
}
// 根据用户选择执行不同的操作函数
void Menu(int choice)
{
switch (choice) {
case 1:
AddCourses();
// 执行录入课程信息操作
break;
case 2:
BrowseCourses();
// 执行浏览课程信息操作
break;
case 3:
QueryCourses();
// 执行查询课程信息操作
break;
case 4:
ModifyCourses();
// 执行修改课程信息操作
break;
case 5:
DeleteCourses();
// 执行删除课程信息操作
break;
case 6:
SortCourses();
// 执行对课程信息进行排序操作
break;
default:
// 处理无效选择的情况,例如显示错误消息
printf("无效的选择,请输入1到6之间的数字。\n");
break;
}
}
3.3 从文件中加载课程信息到内存
// 从文件中加载课程信息到内存
void LoadData(struct Course* courses, int* count)
{
FILE* fp = fopen("./课程管理系统.txt", "r");
// 打开名为课程管理系统.txt的文件以供读取
if (fp == NULL) {
printf("无法打开文件\n");
// 如果文件打开失败,则输出错误信息
return;
}
int i = 0;
// 逐行读取文件中的课程信息,直到文件末尾
// 将每行数据解析并存储到课程信息结构体数组中
while (fscanf(fp, "%s %s %s %s %s %s %s %s", courses[i].number, courses[i].name,
courses[i].type, courses[i].totalHours, courses[i].experimentHours,
courses[i].lectureHours, courses[i].credits, courses[i].semester) == 8) {
i++;
// 每成功读取一行,课程数量加1
}
*count = i;
// 更新课程数量
fclose(fp);
// 关闭文件
}
3.4 将内存中的课程信息保存到文件
// 将内存中的课程信息保存到文件
void SaveData(struct Course* courses, int count)
{
FILE* fp = fopen("./课程管理系统.txt", "w");
// 打开名为课程管理系统.txt的文件以供写入
if (fp == NULL) {
printf("无法打开文件以写入\n");
// 如果文件打开失败,则输出错误信息
return;
}
int i = 0;
for (i = 0; i < count; i++) {
fprintf(fp, "%s %s %s %s %s %s %s %s\n", courses[i].number, courses[i].name,
courses[i].type, courses[i].totalHours, courses[i].experimentHours,
courses[i].lectureHours, courses[i].credits, courses[i].semester);
// 将每门课程的信息按指定格式写入文件
}
fclose(fp);
// 关闭文件
}
4 主要功能函数
4.1 录入课程信息函数
// 录入课程信息函数
void AddCourses()
{
int n;
FILE* fp;
printf("请输入要录入的课程数量:\n");
scanf("%d", &n);
printf("请输入课程信息:\n");
printf("格式如下:001 c语言 必修 10 2 3 4.5 1\n");
printf("编号、名称、性质、总学时、实验学时、授课学时、学分、开课学期\n");
printf("(开课学期中大一上为1,大一下为2,大二上为3依次递推)\n");
struct Course x;
int i = 0;
for (i = 0; i < n; i++) {
getchar(); // 消耗掉输入缓冲中的换行符
printf("请输入第 %d 门课程的信息:\n", i + 1);
printf("课程编号: ");
scanf("%s", x.number);
printf("课程名称: ");
scanf("%s", x.name);
printf("课程性质: ");
scanf("%s", x.type);
printf("总学时: ");
scanf("%s", x.totalHours);
printf("实验学时: ");
scanf("%s", x.experimentHours);
printf("授课学时: ");
scanf("%s", x.lectureHours);
printf("学分: ");
scanf("%s", x.credits);
printf("开课学期: ");
scanf("%s", x.semester);
fp = fopen("./课程管理系统.txt", "a");
fprintf(fp, "%s %s %s %s %s %s %s %s\n", x.number, x.name, x.type,
x.totalHours, x.experimentHours, x.lectureHours, x.credits,
x.semester);
fclose(fp);
printf("第 %d 门课程信息已录入\n", i + 1);
}
}
4.2 浏览课程信息函数
// 浏览课程信息函数
void BrowseCourses()
{
FILE* fp;
struct Course course;
fp = fopen("./课程管理系统.txt", "r"); // 以只读模式打开名为课程管理系统.txt的文件
if (fp == NULL) {
printf("无法打开文件\n"); // 如果文件打开失败,则输出错误信息
return;
}
// 打印表头
printf("课程编号 课程名称 课程性质 总学时 实验学时 授课学时 学分 开课学期\n");
// 逐行读取文件中的课程信息,并按指定格式打印输出
while (fscanf(fp, "%s %s %s %s %s %s %s %s", course.number, course.name,
course.type, course.totalHours, course.experimentHours,
course.lectureHours, course.credits, course.semester) == 8) {
printf("%-8s %-8s %-8s %-6s %-8s %-8s %-4s %-8s\n", course.number, course.name,
course.type, course.totalHours, course.experimentHours, course.lectureHours,
course.credits, course.semester); // 打印每门课程的信息
}
fclose(fp); // 关闭文件
}
4.3 查询课程信息函数
// 查询课程信息函数
void QueryCourses()
{
int choice;
printf("1.按学分查询\n"); // 显示按学分查询的选项
printf("2.按课程性质查询\n"); // 显示按课程性质查询的选项
printf("请选择查询方式:"); // 提示用户选择查询方式
scanf("%d", &choice); // 读取用户选择的查询方式
if (choice == 1) {
char credits[10];
printf("请输入要查询的学分数:"); // 提示用户输入要查询的学分数
scanf("%s", credits); // 读取用户输入的学分数
FILE* fp = fopen("./课程管理系统.txt", "r"); // 以只读模式打开名为课程管理系统.txt的文件
if (fp == NULL) {
printf("无法打开文件\n"); // 如果文件打开失败,则输出错误信息
return;
}
struct Course course;
bool found = false;
while (fscanf(fp, "%s %s %s %s %s %s %s %s", course.number, course.name,
course.type, course.totalHours, course.experimentHours,
course.lectureHours, course.credits, course.semester) == 8) {
if (strcmp(course.credits, credits) == 0) { // 如果课程的学分与用户输入的学分匹配
if (!found) {
printf("课程编号 课程名称 课程性质 总学时 实验学时 授课学时 学分 开课学期\n");
found = true;
}
printf("%-8s %-8s %-8s %-6s %-8s %-8s %-4s %-8s\n", course.number, course.name,
course.type, course.totalHours, course.experimentHours, course.lectureHours,
course.credits, course.semester); // 输出符合条件的课程信息
}
}
if (!found) {
printf("未找到符合条件的课程\n"); // 若未找到符合条件的课程,则提示用户未找到
}
fclose(fp); // 关闭文件
}
else if (choice == 2) {
char type[10];
printf("请输入要查询的课程性质:"); // 提示用户输入要查询的课程性质
scanf("%s", type); // 读取用户输入的课程性质
FILE* fp = fopen("./课程管理系统.txt", "r"); // 以只读模式打开名为课程管理系统.txt的文件
if (fp == NULL) {
printf("无法打开文件\n"); // 如果文件打开失败,则输出错误信息
return;
}
struct Course course;
bool found = false;
while (fscanf(fp, "%s %s %s %s %s %s %s %s", course.number, course.name,
course.type, course.totalHours, course.experimentHours,
course.lectureHours, course.credits, course.semester) == 8) {
if (strcmp(course.type, type) == 0) { // 如果课程的性质与用户输入的性质匹配
if (!found) {
printf("课程编号 课程名称 课程性质 总学时 实验学时 授课学时 学分 开课学期\n");
found = true;
}
// 输出符合条件的课程信息
printf("%-8s %-8s %-8s %-6s %-8s %-8s %-4s %-8s\n", course.number, course.name,
course.type, course.totalHours, course.experimentHours, course.lectureHours,
course.credits, course.semester);
}
}
if (!found) {
printf("未找到符合条件的课程\n"); // 若未找到符合条件的课程,则提示用户未找到
}
fclose(fp); // 关闭文件
}
else {
printf("无效的选择,请选择1或2\n"); // 如果选择无效,则提示用户重新选择
}
}
4.4 修改课程信息函数
void ModifyCourses()
{
char cnt[20];
printf("请输入要修改的课程编号: ");
scanf("%s", cnt); // 读取用户输入的要修改的课程编号
FILE* fp = fopen("./课程管理系统.txt", "r"); // 以只读模式打开名为课程管理系统.txt的文件
if (fp == NULL) {
printf("无法打开文件\n"); // 如果文件打开失败,则输出错误信息
return;
}
struct Course course;
long int position = 0;
bool found = false;
// 遍历文件中的课程信息,查找要修改的课程
while (fscanf(fp, "%s %s %s %s %s %s %s %s", course.number, course.name,
course.type, course.totalHours, course.experimentHours,
course.lectureHours, course.credits, course.semester) == 8) {
if (strcmp(course.number, cnt) == 0) { // 如果找到要修改的课程
found = true;
break;
}
position = ftell(fp); // 记录当前位置
}
fclose(fp); // 关闭文件
if (found) {
// 输出当前课程信息
printf("当前课程信息:\n");
printf("课程编号: %s\n", course.number);
printf("课程名称: %s\n", course.name);
printf("课程性质: %s\n", course.type);
printf("总学时: %s\n", course.totalHours);
printf("实验学时: %s\n", course.experimentHours);
printf("授课学时: %s\n", course.lectureHours);
printf("学分: %s\n", course.credits);
printf("开课学期: %s\n", course.semester);
// 读取新的课程信息
struct Course newCourse;
printf("请输入新的课程信息:\n");
printf("课程名称: ");
scanf("%s", newCourse.name);
printf("课程性质: ");
scanf("%s", newCourse.type);
printf("总学时: ");
scanf("%s", newCourse.totalHours);
printf("实验学时: ");
scanf("%s", newCourse.experimentHours);
printf("授课学时: ");
scanf("%s", newCourse.lectureHours);
printf("学分: ");
scanf("%s", newCourse.credits);
printf("开课学期: ");
scanf("%s", newCourse.semester);
FILE* fp = fopen("./课程管理系统.txt", "r+"); // 以读写模式打开文件
if (fp == NULL) {
printf("无法打开文件\n"); // 如果文件打开失败,则输出错误信息
return;
}
// 定位到要修改的课程信息的位置,并将新的课程信息写入文件
fseek(fp, position, SEEK_SET);
fprintf(fp, "\n%s %s %s %s %s %s %s %s\n", newCourse.number, newCourse.name,
newCourse.type, newCourse.totalHours, newCourse.experimentHours,
newCourse.lectureHours, newCourse.credits, newCourse.semester);
fclose(fp); // 关闭文件
printf("课程信息已成功更新!\n"); // 输出课程信息已成功更新的消息
}
else {
printf("未找到课程编号: %s\n", cnt); // 若未找到要修改的课程,则输出未找到的消息
}
BrowseCourses();
}
4.5 删除课程信息函数
// 删除课程信息函数
void DeleteCourses()
{
int option;
printf("1.删除相同课程编号的课程\n"); // 显示删除相同课程编号的选项
printf("2.删除相同课程名称的课程\n"); // 显示删除相同课程名称的选项
printf("请选择删除方式:"); // 提示用户选择删除方式
scanf("%d", &option); // 读取用户选择的删除方式
if (option == 1 || option == 2) {
char key[20];
printf("请输入要删除的课程标识:"); // 提示用户输入要删除的课程标识
scanf("%s", key); // 读取用户输入的课程标识
FILE* inputFile = fopen("./课程管理系统.txt", "r"); // 以只读模式打开名为课程管理系统.txt的文件
if (inputFile == NULL) {
printf("无法打开文件\n"); // 如果文件打开失败,则输出错误信息
return;
}
FILE* outputFile = fopen("temp.txt", "w"); // 以写入模式创建一个临时文件temp.txt
if (outputFile == NULL) {
printf("无法创建临时文件\n"); // 如果创建临时文件失败,则输出错误信息
fclose(inputFile);
return;
}
// 遍历文件并删除匹配的课程信息
struct Course course;
bool found = false;
while (fscanf(inputFile, "%s %s %s %s %s %s %s %s", course.number, course.name,
course.type, course.totalHours, course.experimentHours,
course.lectureHours, course.credits, course.semester) == 8) {
if ((option == 1 && strcmp(course.number, key) == 0) ||
(option == 2 && strcmp(course.name, key) == 0)) {
found = true;
continue; // 不写入到输出文件,相当于删除
}
fprintf(outputFile, "%s %s %s %s %s %s %s %s\n", course.number, course.name,
course.type, course.totalHours, course.experimentHours, course.lectureHours,
course.credits, course.semester); // 将未匹配的课程信息写入输出文件
}
fclose(inputFile); // 关闭输入文件
fclose(outputFile); // 关闭输出文件
if (found) {
remove("课程管理系统.txt"); // 删除原文件
rename("temp.txt", "课程管理系统.txt"); // 重命名临时文件为原文件名
printf("课程信息已成功删除!\n"); // 输出课程信息已成功删除的消息
}
else {
remove("temp.txt"); // 删除临时文件
printf("未找到要删除的课程信息\n"); // 若未找到要删除的课程,则输出未找到的消息
}
}
else {
printf("无效的选择,请选择1或2\n"); // 如果选择无效,则输出提示消息
}
BrowseCourses();
}
4.6 排序课程信息函数
// 按开课学期对课程信息进行排序的函数
void SortCourses()
{
struct Course courses[100];
int count = 0;
LoadData(courses, &count); // 从文件中加载课程信息
// 使用冒泡排序按开课学期进行排序
int i, j;
for (i = 0; i < count - 1; i++) {
for (j = 0; j < count - i - 1; j++) {
// 将开课学期转换为整数进行比较
int semester1 = atoi(courses[j].semester);
int semester2 = atoi(courses[j + 1].semester);
if (semester1 > semester2) {
struct Course temp = courses[j];
courses[j] = courses[j + 1];
courses[j + 1] = temp;
}
}
}
// 保存排序后的课程信息到文件
SaveData(courses, count);
printf("课程信息已按开课学期排序!\n");
BrowseCourses();
}
001 C 必修 10 2 3 4 1
002 数学 必修 45 3 3 3 3
010 高数 选修 6 6 6 6 6
5 完整代码块
5.1 CourseManagement.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
// 定义课程结构体
// 为了测试方便,都设置char类型
struct Course{
char number[20]; // 课程编号
char name[50]; // 课程名称
char type[10]; // 课程性质(如必修、选修)
char totalHours[20]; // 总学时
char experimentHours[20]; // 实验学时
char lectureHours[20]; // 授课学时
char credits[10]; // 学分
char semester[20]; // 开课学期,开课学期中大一上为1,大一下为2,大二上为3依次递推
};
// 打印主菜单函数
void PrintMenu();
// 根据用户选择执行不同的操作函数
void Menu(int choice);
// 从文件中加载课程信息到内存
void LoadData(struct Course* courses, int* count);
// 将内存中的课程信息保存到文件
void SaveData(struct Course* courses, int count);
// 录入课程信息函数
void AddCourses();
// 浏览课程信息函数
void BrowseCourses();
// 查询课程信息函数
void QueryCourses();
// 修改课程信息函数
void ModifyCourses();
// 删除课程信息函数
void DeleteCourses();
// 按课程编号对课程信息进行排序的函数
void SortCourses();
5.2 CourseManagement.c
#include "CourseManagement.h"
// 打印主菜单函数
void PrintMenu()
{
printf(" *****课程管理系统***** \n");
// 打印系统名称
printf("* 1.录入课程信息 *\n");
// 选项1:录入课程信息
printf("* 2.课程信息浏览 *\n");
// 选项2:浏览课程信息
printf("* 3.课程信息查询 *\n");
// 选项3:查询课程信息
printf("* 4.课程信息修改 *\n");
// 选项4:修改课程信息
printf("* 5.删除课程信息 *\n");
// 选项5:删除课程信息
printf("* 6.课程信息排序 *\n");
// 选项6:对课程信息进行排序
printf("* 0.退出课程系统 *\n");
// 选项0:退出系统
printf("请选择操作:\n");
// 提示用户选择操作
}
// 根据用户选择执行不同的操作函数
void Menu(int choice)
{
switch (choice) {
case 1:
AddCourses();
// 执行录入课程信息操作
break;
case 2:
BrowseCourses();
// 执行浏览课程信息操作
break;
case 3:
QueryCourses();
// 执行查询课程信息操作
break;
case 4:
ModifyCourses();
// 执行修改课程信息操作
break;
case 5:
DeleteCourses();
// 执行删除课程信息操作
break;
case 6:
SortCourses();
// 执行对课程信息进行排序操作
break;
default:
// 处理无效选择的情况,例如显示错误消息
printf("无效的选择,请输入1到6之间的数字。\n");
break;
}
}
// 从文件中加载课程信息到内存
void LoadData(struct Course* courses, int* count)
{
FILE* fp = fopen("./课程管理系统.txt", "r");
// 打开名为课程管理系统.txt的文件以供读取
if (fp == NULL) {
printf("无法打开文件\n");
// 如果文件打开失败,则输出错误信息
return;
}
int i = 0;
// 逐行读取文件中的课程信息,直到文件末尾
// 将每行数据解析并存储到课程信息结构体数组中
while (fscanf(fp, "%s %s %s %s %s %s %s %s", courses[i].number, courses[i].name,
courses[i].type, courses[i].totalHours, courses[i].experimentHours,
courses[i].lectureHours, courses[i].credits, courses[i].semester) == 8) {
i++;
// 每成功读取一行,课程数量加1
}
*count = i;
// 更新课程数量
fclose(fp);
// 关闭文件
}
// 将内存中的课程信息保存到文件
void SaveData(struct Course* courses, int count)
{
FILE* fp = fopen("./课程管理系统.txt", "w");
// 打开名为课程管理系统.txt的文件以供写入
if (fp == NULL) {
printf("无法打开文件以写入\n");
// 如果文件打开失败,则输出错误信息
return;
}
int i = 0;
for (i = 0; i < count; i++) {
fprintf(fp, "%s %s %s %s %s %s %s %s\n", courses[i].number, courses[i].name,
courses[i].type, courses[i].totalHours, courses[i].experimentHours,
courses[i].lectureHours, courses[i].credits, courses[i].semester);
// 将每门课程的信息按指定格式写入文件
}
fclose(fp);
// 关闭文件
}
// 录入课程信息函数
void AddCourses()
{
int n;
FILE* fp;
printf("请输入要录入的课程数量:\n");
scanf("%d", &n);
printf("请输入课程信息:\n");
printf("格式如下:001 c语言 必修 10 2 3 4.5 1\n");
printf("编号、名称、性质、总学时、实验学时、授课学时、学分、开课学期\n");
printf("(开课学期中大一上为1,大一下为2,大二上为3依次递推)\n");
struct Course x;
int i = 0;
for (i = 0; i < n; i++) {
getchar(); // 消耗掉输入缓冲中的换行符
printf("请输入第 %d 门课程的信息:\n", i + 1);
printf("课程编号: ");
scanf("%s", x.number);
printf("课程名称: ");
scanf("%s", x.name);
printf("课程性质: ");
scanf("%s", x.type);
printf("总学时: ");
scanf("%s", x.totalHours);
printf("实验学时: ");
scanf("%s", x.experimentHours);
printf("授课学时: ");
scanf("%s", x.lectureHours);
printf("学分: ");
scanf("%s", x.credits);
printf("开课学期: ");
scanf("%s", x.semester);
fp = fopen("./课程管理系统.txt", "a");
fprintf(fp, "%s %s %s %s %s %s %s %s\n", x.number, x.name, x.type,
x.totalHours, x.experimentHours, x.lectureHours, x.credits,
x.semester);
fclose(fp);
printf("第 %d 门课程信息已录入\n", i + 1);
}
}
// 浏览课程信息函数
void BrowseCourses()
{
FILE* fp;
struct Course course;
fp = fopen("./课程管理系统.txt", "r"); // 以只读模式打开名为课程管理系统.txt的文件
if (fp == NULL) {
printf("无法打开文件\n"); // 如果文件打开失败,则输出错误信息
return;
}
// 打印表头
printf("课程编号 课程名称 课程性质 总学时 实验学时 授课学时 学分 开课学期\n");
// 逐行读取文件中的课程信息,并按指定格式打印输出
while (fscanf(fp, "%s %s %s %s %s %s %s %s", course.number, course.name,
course.type, course.totalHours, course.experimentHours,
course.lectureHours, course.credits, course.semester) == 8) {
printf("%-8s %-8s %-8s %-6s %-8s %-8s %-4s %-8s\n", course.number, course.name,
course.type, course.totalHours, course.experimentHours, course.lectureHours,
course.credits, course.semester); // 打印每门课程的信息
}
fclose(fp); // 关闭文件
}
// 查询课程信息函数
void QueryCourses()
{
int choice;
printf("1.按学分查询\n"); // 显示按学分查询的选项
printf("2.按课程性质查询\n"); // 显示按课程性质查询的选项
printf("请选择查询方式:"); // 提示用户选择查询方式
scanf("%d", &choice); // 读取用户选择的查询方式
if (choice == 1) {
char credits[10];
printf("请输入要查询的学分数:"); // 提示用户输入要查询的学分数
scanf("%s", credits); // 读取用户输入的学分数
FILE* fp = fopen("./课程管理系统.txt", "r"); // 以只读模式打开名为课程管理系统.txt的文件
if (fp == NULL) {
printf("无法打开文件\n"); // 如果文件打开失败,则输出错误信息
return;
}
struct Course course;
bool found = false;
while (fscanf(fp, "%s %s %s %s %s %s %s %s", course.number, course.name,
course.type, course.totalHours, course.experimentHours,
course.lectureHours, course.credits, course.semester) == 8) {
if (strcmp(course.credits, credits) == 0) { // 如果课程的学分与用户输入的学分匹配
if (!found) {
printf("课程编号 课程名称 课程性质 总学时 实验学时 授课学时 学分 开课学期\n");
found = true;
}
printf("%-8s %-8s %-8s %-6s %-8s %-8s %-4s %-8s\n", course.number, course.name,
course.type, course.totalHours, course.experimentHours, course.lectureHours,
course.credits, course.semester); // 输出符合条件的课程信息
}
}
if (!found) {
printf("未找到符合条件的课程\n"); // 若未找到符合条件的课程,则提示用户未找到
}
fclose(fp); // 关闭文件
}
else if (choice == 2) {
char type[10];
printf("请输入要查询的课程性质:"); // 提示用户输入要查询的课程性质
scanf("%s", type); // 读取用户输入的课程性质
FILE* fp = fopen("./课程管理系统.txt", "r"); // 以只读模式打开名为课程管理系统.txt的文件
if (fp == NULL) {
printf("无法打开文件\n"); // 如果文件打开失败,则输出错误信息
return;
}
struct Course course;
bool found = false;
while (fscanf(fp, "%s %s %s %s %s %s %s %s", course.number, course.name,
course.type, course.totalHours, course.experimentHours,
course.lectureHours, course.credits, course.semester) == 8) {
if (strcmp(course.type, type) == 0) { // 如果课程的性质与用户输入的性质匹配
if (!found) {
printf("课程编号 课程名称 课程性质 总学时 实验学时 授课学时 学分 开课学期\n");
found = true;
}
// 输出符合条件的课程信息
printf("%-8s %-8s %-8s %-6s %-8s %-8s %-4s %-8s\n", course.number, course.name,
course.type, course.totalHours, course.experimentHours, course.lectureHours,
course.credits, course.semester);
}
}
if (!found) {
printf("未找到符合条件的课程\n"); // 若未找到符合条件的课程,则提示用户未找到
}
fclose(fp); // 关闭文件
}
else {
printf("无效的选择,请选择1或2\n"); // 如果选择无效,则提示用户重新选择
}
}
// 修改课程信息函数
void ModifyCourses()
{
char cnt[20];
printf("请输入要修改的课程编号: ");
scanf("%s", cnt); // 读取用户输入的要修改的课程编号
FILE* fp = fopen("./课程管理系统.txt", "r"); // 以只读模式打开名为课程管理系统.txt的文件
if (fp == NULL) {
printf("无法打开文件\n"); // 如果文件打开失败,则输出错误信息
return;
}
struct Course course;
long int position = 0;
bool found = false;
// 遍历文件中的课程信息,查找要修改的课程
while (fscanf(fp, "%s %s %s %s %s %s %s %s", course.number, course.name,
course.type, course.totalHours, course.experimentHours,
course.lectureHours, course.credits, course.semester) == 8) {
if (strcmp(course.number, cnt) == 0) { // 如果找到要修改的课程
found = true;
break;
}
position = ftell(fp); // 记录当前位置
}
fclose(fp); // 关闭文件
if (found) {
// 输出当前课程信息
printf("当前课程信息:\n");
printf("课程编号: %s\n", course.number);
printf("课程名称: %s\n", course.name);
printf("课程性质: %s\n", course.type);
printf("总学时: %s\n", course.totalHours);
printf("实验学时: %s\n", course.experimentHours);
printf("授课学时: %s\n", course.lectureHours);
printf("学分: %s\n", course.credits);
printf("开课学期: %s\n", course.semester);
// 读取新的课程信息
struct Course newCourse;
printf("请输入新的课程信息:\n");
printf("课程名称: ");
scanf("%s", newCourse.name);
printf("课程性质: ");
scanf("%s", newCourse.type);
printf("总学时: ");
scanf("%s", newCourse.totalHours);
printf("实验学时: ");
scanf("%s", newCourse.experimentHours);
printf("授课学时: ");
scanf("%s", newCourse.lectureHours);
printf("学分: ");
scanf("%s", newCourse.credits);
printf("开课学期: ");
scanf("%s", newCourse.semester);
FILE* fp = fopen("./课程管理系统.txt", "r+"); // 以读写模式打开文件
if (fp == NULL) {
printf("无法打开文件\n"); // 如果文件打开失败,则输出错误信息
return;
}
// 定位到要修改的课程信息的位置,并将新的课程信息写入文件
fseek(fp, position, SEEK_SET);
fprintf(fp, "\n%s %s %s %s %s %s %s %s\n", newCourse.number, newCourse.name,
newCourse.type, newCourse.totalHours, newCourse.experimentHours,
newCourse.lectureHours, newCourse.credits, newCourse.semester);
fclose(fp); // 关闭文件
printf("课程信息已成功更新!\n"); // 输出课程信息已成功更新的消息
}
else {
printf("未找到课程编号: %s\n", cnt); // 若未找到要修改的课程,则输出未找到的消息
}
BrowseCourses();
}
// 删除课程信息函数
void DeleteCourses()
{
int option;
printf("1.删除相同课程编号的课程\n"); // 显示删除相同课程编号的选项
printf("2.删除相同课程名称的课程\n"); // 显示删除相同课程名称的选项
printf("请选择删除方式:"); // 提示用户选择删除方式
scanf("%d", &option); // 读取用户选择的删除方式
if (option == 1 || option == 2) {
char key[20];
printf("请输入要删除的课程标识:"); // 提示用户输入要删除的课程标识
scanf("%s", key); // 读取用户输入的课程标识
FILE* inputFile = fopen("./课程管理系统.txt", "r"); // 以只读模式打开名为课程管理系统.txt的文件
if (inputFile == NULL) {
printf("无法打开文件\n"); // 如果文件打开失败,则输出错误信息
return;
}
FILE* outputFile = fopen("temp.txt", "w"); // 以写入模式创建一个临时文件temp.txt
if (outputFile == NULL) {
printf("无法创建临时文件\n"); // 如果创建临时文件失败,则输出错误信息
fclose(inputFile);
return;
}
// 遍历文件并删除匹配的课程信息
struct Course course;
bool found = false;
while (fscanf(inputFile, "%s %s %s %s %s %s %s %s", course.number, course.name,
course.type, course.totalHours, course.experimentHours,
course.lectureHours, course.credits, course.semester) == 8) {
if ((option == 1 && strcmp(course.number, key) == 0) ||
(option == 2 && strcmp(course.name, key) == 0)) {
found = true;
continue; // 不写入到输出文件,相当于删除
}
fprintf(outputFile, "%s %s %s %s %s %s %s %s\n", course.number, course.name,
course.type, course.totalHours, course.experimentHours, course.lectureHours,
course.credits, course.semester); // 将未匹配的课程信息写入输出文件
}
fclose(inputFile); // 关闭输入文件
fclose(outputFile); // 关闭输出文件
if (found) {
remove("课程管理系统.txt"); // 删除原文件
rename("temp.txt", "课程管理系统.txt"); // 重命名临时文件为原文件名
printf("课程信息已成功删除!\n"); // 输出课程信息已成功删除的消息
}
else {
remove("temp.txt"); // 删除临时文件
printf("未找到要删除的课程信息\n"); // 若未找到要删除的课程,则输出未找到的消息
}
}
else {
printf("无效的选择,请选择1或2\n"); // 如果选择无效,则输出提示消息
}
BrowseCourses();
}
// 按开课学期对课程信息进行排序的函数
void SortCourses()
{
struct Course courses[100];
int count = 0;
LoadData(courses, &count); // 从文件中加载课程信息
// 使用冒泡排序按开课学期进行排序
int i, j;
for (i = 0; i < count - 1; i++) {
for (j = 0; j < count - i - 1; j++) {
// 将开课学期转换为整数进行比较
int semester1 = atoi(courses[j].semester);
int semester2 = atoi(courses[j + 1].semester);
if (semester1 > semester2) {
struct Course temp = courses[j];
courses[j] = courses[j + 1];
courses[j + 1] = temp;
}
}
}
// 保存排序后的课程信息到文件
SaveData(courses, count);
printf("课程信息已按开课学期排序!\n");
BrowseCourses();
}
5.3 Test.c
#include "CourseManagement.h"
int main() {
int choice;
do {
PrintMenu();
scanf("%d", &choice);
if (choice >= 1 && choice <= 6) {
Menu(choice);
}
else if (choice == 0) {
printf("您已退出课程系统\n");
break;
}
else {
printf("输入错误,请重新输入一个在0到7之间的整数!\n");
}
} while (1);
return 0;
}