C语言-课程管理系统-大作业

C语言编写课程管理系统

  • 1 需求分析
  • 2 需要查的知识点
  • 3 数据结构和基础函数功能
    • 3.1 课程数据结构
    • 3.2 菜单和选择项
    • 3.3 从文件中加载课程信息到内存
    • 3.4 将内存中的课程信息保存到文件
    • 3.5 将输入的字符串格式化为课程信息结构体
  • 4 主要功能函数
    • 4.1 录入课程信息函数
    • 4.2 浏览课程信息函数
    • 4.3 查询课程信息函数
    • 4.4 修改课程信息函数
    • 4.5 删除课程信息函数
    • 4.6 排序课程信息函数
  • !!!修改课程信息的函数有bug !!!
  • 5 完整代码块
    • 5.1 CourseManagement.h
    • 5.2 CourseManagement.c
    • 5.3 Test.c

着急交作业的同学可以直接跳跃到 5 完整代码块

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);// 关闭文件
}

3.5 将输入的字符串格式化为课程信息结构体

// 将输入的字符串格式化为课程信息结构体
void ChangeDataFormat(char* input, struct Course* course)
{sscanf(input, "%s %s %s %s %s %s %s %s",course->number, course->name, course->type,course->totalHours, course->experimentHours,course->lectureHours, course->credits, course->semester);}

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, "%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.txtif (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

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

!!!修改课程信息的函数有bug !!!

额,不知道怎么解决了,有点头疼。可以直接把这个功能注释掉。
或者不用管他,但是不使用4 修改课程信息,坦诚地对老师说这个功能没有实现。
需求分析里面是没写修改功能。
笔者写了也没有写出来。实在头疼。

在这里插入图片描述
在这里插入图片描述
老是错位一行,不知道如何处理。

目前这个bug十分严重,建议不使用这个函数,放置着做摆设。
在这里插入图片描述
但是修改第一行的数据没有问题。

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 ChangeDataFormat(char* input, struct Course* course);
// 录入课程信息函数
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 ChangeDataFormat(char* input, struct Course* course)
{sscanf(input, "%s %s %s %s %s %s %s %s",course->number, course->name, course->type,course->totalHours, course->experimentHours,course->lectureHours, course->credits, course->semester);}// 录入课程信息函数
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, "%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.txtif (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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/10520.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024全新小狐狸AI免授权源码

源码安装说明&#xff1a; 下 载 地 址 &#xff1a; runruncode.com/php/19757.html 1. 在宝塔新建一个站点&#xff0c;选择 PHP 版本为 7.2、7.3 或 7.4。将压缩包上传到站点的根目录&#xff0c;并设置运行目录为 /public。 2. 导入数据库文件&#xff0c;该文件位于 …

Python装饰器带括号和不带括号的理解

装饰器是 Python 中一个强大且灵活的特性&#xff0c;允许用户在不修改原有函数或类定义的基础上&#xff0c;为其增加额外功能。 今天在尝试自定义 Python 装饰器的时候遇到了一个问题&#xff0c;因为以前一直是使用装饰器&#xff0c;基本没有自定义过装饰器&#xff0c;所…

vue3点击添加小狗图片,vue3拆分脚本

我悄悄蒙上你的眼睛 模板和样式 <template><div class"XueXi_Hooks"><img v-for"(dog, index) in dog1List" :src"dog" :key"index" /><button click"addDog1">点我添加狗1</button><hr …

WPF之工具栏菜单栏功能区。

1&#xff0c;菜单栏&#xff0c;工具栏&#xff0c;状态栏。 1.1&#xff0c;Menu中可添加菜单分隔条<Separator></Separator>作为分割线&#xff0c;使用Separator可以通过改变其template来自定义&#xff0c;Separator是无焦点的&#xff0c;如果简单的在MenuIt…

品鉴中的平衡之美:如何欣赏红酒的口感与风格和谐

品鉴云仓酒庄雷盛红酒的过程&#xff0c;是对其口感与风格和谐的追求和欣赏。平衡是红酒品质的重要标志之一&#xff0c;它体现在红酒的色泽、香气、口感和余味等多个方面。通过欣赏红酒的平衡之美&#xff0c;我们可以更好地领略其精妙之处&#xff0c;感受其带来的美妙滋味。…

【Unity Animation 2D】Unity Animation 2D骨骼绑定与动画制作

一、图片格式为png格式&#xff0c;并且角色各部分分离 图片参数设置 需要将Sprite Mode设置为Single&#xff0c;否则图片不能作为一个整体 1、创建骨骼 1.1 旋转Create Bone&#xff0c;点击鼠标左键确定骨骼位置&#xff0c;移动鼠标再次点击鼠标左键确定骨骼&#xff0c…

大数据面试题第一期*4

题1、HDFS存储机制 &#xff08;1&#xff09;客户端向namenode请求上传文件 &#xff0c;namenode检查目标文件是否已存在 &#xff0c;父目录是否存在。 &#xff08;2&#xff09;namenode返回是否可以上传。 &#xff08;3&#xff09;客户端请求第一个 block上传到哪几个d…

嵌入式C语言高级教程:实现基于STM32的智能健康监测手环

智能健康监测手环能够实时监控用户的生理参数&#xff0c;如心率、体温和活动量&#xff0c;对于健康管理和疾病预防非常有帮助。本教程将指导您如何在STM32微控制器上实现一个基本的智能健康监测手环。 一、开发环境准备 硬件要求 微控制器&#xff1a;STM32L476RG&#xf…

RS3236-3.3YUTDN4功能和参数介绍及PDF资料

RS3236-3.3YUTDN4功能和参数介绍及PDF资料-公司新闻-配芯易-深圳市亚泰盈科电子有限公司 品牌: RUNIC(润石) 封装: XDFN-4-EP(1x1) 描述: 带过温保护 输出类型: 固定 最大输入电压: 7.5V 输出电压: 3.3V 最大输出电流: 500mA RS3236-3.3YUTDN4 是一款低压差线性稳压器&#x…

PX4FMU和PX4IO最底层启动过程分析(下)

PX4FMU和PX4IO最底层启动过程分析&#xff08;下&#xff09; PX4FMU的系统启动函数为nash_main(int argc,char *argv[]) PX4IO的系统启动函数为nash_start(int argc,char *argv[]) PX4FMU启动函数nash_main(int argc,char *argv[]) 首先分析一下nash_main(int argc,char *a…

高效视频剪辑:视频批量调色,如何利用色调调整提升效率

在视频剪辑的后期处理中&#xff0c;调色是一个至关重要的环节。它不仅能够改变视频的整体氛围和风格&#xff0c;还能够突出视频的重点&#xff0c;增强观众的视觉体验。然而&#xff0c;对于大量的视频素材进行逐个调色处理&#xff0c;无疑会耗费大量的时间和精力。我们可以…

软件安装及YOLOv8环境配置及验证

先附上本章中所用到的软件及环境安装包&#xff0c;还有YOLOv8各任务权重&#xff1a; 软件及环境配置链接&#xff1a;https://pan.baidu.com/s/1-n2HJybicA6vW1YXfGRtcA 提取码&#xff1a;6vh8 YOLOv8各权重&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1ApYUrJ_s…

C++相关概念和易错语法(12)(迭代器、string容量调整)

1.迭代器&#xff08;以string为例&#xff09; &#xff08;1&#xff09;基本理解&#xff1a;在我们刚接触迭代器的时候&#xff0c;我们可以将迭代器理解为改造过的“指针”&#xff0c;这是一个新的类型&#xff0c;指向对应容器中的各个元素。我们可以像指针那样对迭代器…

Lombok介绍、使用方法和安装

目录 1 Lombok背景介绍 2 Lombok使用方法 2.1 Data 2.2 Getter/Setter 2.3 NonNull 2.4 Cleanup 2.5 EqualsAndHashCode 2.6 ToString 2.7 NoArgsConstructor, RequiredArgsConstructor and AllArgsConstructor 3 Lombok工作原理分析 4. Lombok的优缺点 5. 总结 1 …

Idea入门:一分钟创建一个Java工程

一&#xff0c;新建一个Java工程 1&#xff0c;启动Idea后&#xff0c;选择 [New Project] 2&#xff0c;完善工程信息 填写工程名称&#xff0c;根据实际用途取有意义的英文名称选择Java语言&#xff0c;可以看到还支持Kotlin、Javascript等语言选择包管理和项目构建工具Mav…

LVS的三种工作模式---(DR/TUN/NAT)

目录 一、NAT模式&#xff08;LVS-NAT&#xff09; 二、IP隧道模式&#xff08;LVS-TUN&#xff09; 三、DR模型--直接路由模式&#xff08;LVS-DR&#xff09; LVS/DR模式ARP抑制 原因&#xff1a; LVS的DR工作模式及配置&#xff1a; LVS的NAT工作模式及配置&#xff1…

PyQt6--Python桌面开发(7.QTextEdit多行富文本框控件)

QTextEdit多行富文本框控件 保存文件到本地QLine多行文本框.ui import sys import time from PyQt6.QtGui import QValidator,QIntValidator from PyQt6.QtWidgets import QApplication,QLabel,QLineEdit,QTextEdit from PyQt6 import uic,QtGuiif __name__ __main__:appQApp…

二叉树进阶 --- 上

目录 1. 二叉搜索树的概念及结构 1.1. 二叉搜索树的概念 1.2. 二叉搜索树的结构样例 2. 二叉搜索树的实现 2.1. insert 的非递归实现 2.2. find 的非递归实现 2.3. erase 的非递归实现 2.3.1. 第一种情况&#xff1a;所删除的节点的左孩子为空 2.3.1.1. 错误的代码 2…

基本QinQ

拓扑图 配置 开启LLDP功能&#xff0c;查看是否能通过QinQ隧道透传 sysname AR1 # lldp enable # interface GigabitEthernet0/0/0.10dot1q termination vid 10ip address 12.1.1.1 255.255.255.0 arp broadcast enable # sysname AR2 # lldp enable # interface GigabitE…

地磁暴红色预警来袭,普通人该如何应对?绝绝子的防护指南来了

近日&#xff0c;国家空间天气监测预警中心发布了一则令人瞩目的消息——地磁暴红色预警。这一预警不仅提醒我们地磁暴即将影响我国的电离层和低轨卫星&#xff0c;更让我们深刻认识到地球空间环境的脆弱性和复杂性。对于普通公众而言&#xff0c;地磁暴的概念可能相对陌生&…