目 录
1 实验目的
- 熟悉C语言程序设计,掌握结构体、链表等数据结构的使用。
- 学习文件操作,实现数据的读取和存储。
- 综合运用函数、条件语句和循环等基本编程技巧,完成一个较为复杂的程序。
- 锻炼问题解决能力,培养编程思维和代码规范意识。
2 实验内容
(1)设计数据结构:定义一个招生信息的结构体,包含年份、省份、科目、专业、招生计划、批次、最高分、最低分和平均分等字段。
(2)文件操作:利用文件读写函数,实现招生信息的持久化存储,将数据保存在.csv文件中,以逗号分隔各字段。
(3)实现基本功能:
①新增数据: 用户可以添加新的招生信息到系统中,新增的数据会追加到原文件中。
②删除数据: 用户可以删除特定年份和专业的招生信息,包括删除一个数据和多个数据。
③修改数据: 用户可以修改特定年份和专业的招生信息,包括修改一个数据和多个数据。
④查询数据:
查询某年度所有专业的录取信息。
查询某年度所有专业录取的最高分和最低分。
查询某年度所有专业的最高分、最低分和平均分,并按升序或降序显示。
查询某专业不同年度的最高分、最低分和平均分,并按升序或降序显示。
(4)实现扩展功能:
①数据统计功能:统计某年度招生计划总人数、录取的专业数量等。
②排序功能:根据用户需求,实现招生信息的排序功能,如按照最高分或最低分进行排序。
③其他根据实际需求添加的功能,如数据分析、可视化展示等。
3 实验要求
(1)用C语言实现程序设计;
(2)利用结构体、链表等实现招生信息的管理;
(3)系统各个功能模块采用函数实现(尽量少用全局变量,要规范使用函数参数);
(4)界面提示信息丰富有效,可包含二级菜单;程序必须有注释,变量、函数命名必须要规范;
(5)查询排序方法要采用高效排序算法。
4 功能模块
(1)增加数据:实现一个函数,接受用户输入的招生信息,将其添加到链表中。
(2)删除数据:实现函数,允许用户删除指定的招生信息或多个招生信息。
(3)修改数据:函数接受用户输入的修改内容,并根据用户指定的条件修改链表中的相应招生信息。
(4)查询功能:
①查询某年度所有专业的录取信息:遍历链表,输出满足年份条件的所有招生信息。
②查询某年度所有专业录取的最高分和最低分:遍历链表,找到指定年份的招生信息,计算最高分和最低分并输出。
③查询某年度所有专业的最高分、最低分和平均分按升序或降序显示:先计算每个专业的平均分,然后进行排序输出。
④查询某专业不同年度的最高分、最低分和平均分按升序或降序显示:遍历链表,找到指定专业的招生信息,计算并排序输出。
图 1 功能模块图
5 系统设计
5.1 数据结构设计
// 定义招生信息的结构体
typedef struct {
char year[5]; // 年份
char category[20]; // 科类
char major[50]; // 专业
char batch[20]; // 批次
int max_score; // 最高分
int min_score; // 最低分
float avg_score; // 平均分
} AdmissionInfo;//招生信息
// 定义链表节点的结构体
typedef struct Node {
AdmissionInfo data; // 存储招生信息的数据
struct Node* next; // 指向下一个节点的指针
} Node;
Node* head = NULL; // 链表头指针,初始化为空
5.2 函数接口
void loadData(); // 从文件加载数据
void saveData(); // 保存数据到文件
void addData(); // 添加数据
void deleteData(); // 删除数据
void modifyData(); // 修改数据
void queryData(); // 查询数据
void sortData(Node** array, int size, int (*cmp)(const void *, const void *)); // 排序数据
void displayData(Node* n); // 显示数据
void displayMenu(); // 显示主菜单
void displayQueryMenu(); // 显示查询菜单
void displaySortMenu(); // 显示排序菜单
Node* createNode(AdmissionInfo data); // 创建新节点
Node* findNodeByYear(char* year); // 根据年份查找节点
Node* findNodeByYearAndMajor(char* year, char* major); // 根据年份和专业查找节点
void insertNode(Node* newNode); // 插入节点
void deleteNode(Node* targetNode); // 删除节点
Node** createNodeArray(int *size); // 创建节点数组
Node** createFilteredNodeArrayByYear(int *size, char* year); // 根据年份创建筛选后的节点数组
Node** createFilteredNodeArrayByMajor(int *size, char* major); // 根据专业创建筛选后的节点数组
// 比较函数,用于排序
int compareByMaxScoreAsc(const void *a, const void *b); // 按最高分升序比较
int compareByMaxScoreDesc(const void *a, const void *b); // 按最高分降序比较
int compareByMinScoreAsc(const void *a, const void *b); // 按最低分升序比较
int compareByMinScoreDesc(const void *a, const void *b); // 按最低分降序比较
int compareByAvgScoreAsc(const void *a, const void *b); // 按平均分升序比较
int compareByAvgScoreDesc(const void *a, const void *b); // 按平均分降序比较
5.3 程序流程
图 2 程序流程图
6. 实现与测试
6.1 代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_PROF 1000 // 最大专业数量,定义最大可处理的专业数量
// 定义招生信息的结构体
typedef struct {
char year[5]; // 年份
char category[20]; // 科类
char major[50]; // 专业
char batch[20]; // 批次
int max_score; // 最高分
int min_score; // 最低分
float avg_score; // 平均分
} AdmissionInfo;
// 定义链表节点的结构体
typedef struct Node {
AdmissionInfo data; // 存储招生信息的数据
struct Node* next; // 指向下一个节点的指针
} Node;
Node* head = NULL; // 链表头指针,初始化为空
// 函数声明
void loadData(); // 从文件加载数据
void saveData(); // 保存数据到文件
void addData(); // 添加数据
void deleteData(); // 删除数据
void modifyData(); // 修改数据
void queryData(); // 查询数据
void sortData(Node** array, int size, int (*cmp)(const void *, const void *)); // 排序数据
void displayData(Node* n); // 显示数据
void displayMenu(); // 显示主菜单
void displayQueryMenu(); // 显示查询菜单
void displaySortMenu(); // 显示排序菜单
Node* createNode(AdmissionInfo data); // 创建新节点
Node* findNodeByYear(char* year); // 根据年份查找节点
Node* findNodeByYearAndMajor(char* year, char* major); // 根据年份和专业查找节点
void insertNode(Node* newNode); // 插入节点
void deleteNode(Node* targetNode); // 删除节点
Node** createNodeArray(int *size); // 创建节点数组
Node** createFilteredNodeArrayByYear(int *size, char* year); // 根据年份创建筛选后的节点数组
Node** createFilteredNodeArrayByMajor(int *size, char* major); // 根据专业创建筛选后的节点数组
// 比较函数,用于排序
int compareByMaxScoreAsc(const void *a, const void *b); // 按最高分升序比较
int compareByMaxScoreDesc(const void *a, const void *b); // 按最高分降序比较
int compareByMinScoreAsc(const void *a, const void *b); // 按最低分升序比较
int compareByMinScoreDesc(const void *a, const void *b); // 按最低分降序比较
int compareByAvgScoreAsc(const void *a, const void *b); // 按平均分升序比较
int compareByAvgScoreDesc(const void *a, const void *b); // 按平均分降序比较
int main() {
int choice;
loadData(); // 加载数据
while (1) {
displayMenu(); // 显示主菜单
scanf("%d", &choice);
switch (choice) {
case 1:
addData(); // 增加数据
break;
case 2:
deleteData(); // 删除数据
break;
case 3:
modifyData(); // 修改数据
break;
case 4:
queryData(); // 查询数据
break;
case 5:
saveData(); // 保存数据到文件
printf("数据已保存到文件中。\n");
exit(0); // 退出程序
default:
printf("无效的选择,请重新输入。\n"); // 无效选择处理
}
}
return 0;
}
// 从文件加载数据
void loadData() {
FILE* file = fopen("score.csv", "r");
if (!file) {
printf("无法打开文件。\n");
return;
}
char line[256];
fgets(line, sizeof(line), file); // 跳过标题行
while (fgets(line, sizeof(line), file)) {
AdmissionInfo info;
sscanf(line, "\"%[^\"]\",\"%[^\"]\",\"%[^\"]\",\"%[^\"]\",\"%d\",\"%d\",\"%f\"",
info.year, info.category, info.major, info.batch, &info.max_score, &info.min_score, &info.avg_score);
Node* newNode = createNode(info); // 创建新节点
insertNode(newNode); // 插入节点到链表
}
fclose(file);
}
// 保存数据到文件
void saveData() {
FILE* file = fopen("score.csv", "w");
if (!file) {
printf("无法打开文件。\n");
return;
}
fprintf(file, "\"年份\",\"科类\",\"专业\",\"批次\",\"最高分\",\"最低分\",\"平均分\"\n");
Node* current = head;
while (current) {
fprintf(file, "\"%s\",\"%s\",\"%s\",\"%s\",\"%d\",\"%d\",\"%.2f\"\n",
current->data.year, current->data.category, current->data.major, current->data.batch,
current->data.max_score, current->data.min_score, current->data.avg_score);
current = current->next;
}
fclose(file);
}
// 添加数据
void addData() {
AdmissionInfo info;
printf("请输入年份:");
scanf("%s", info.year);
printf("请输入科类:");
scanf("%s", info.category);
printf("请输入专业:");
scanf("%s", info.major);
printf("请输入批次:");
scanf("%s", info.batch);
printf("请输入最高分:");
scanf("%d", &info.max_score);
printf("请输入最低分:");
scanf("%d", &info.min_score);
printf("请输入平均分:");
scanf("%f", &info.avg_score);
Node* newNode = createNode(info); // 创建新节点
insertNode(newNode); // 插入节点到链表
printf("数据已添加。\n");
}
// 删除数据
void deleteData() {
char year[5];
char major[50];
printf("请输入要删除的年份:");
scanf("%s", year);
printf("请输入要删除的专业:");
scanf("%s", major);
Node* targetNode = findNodeByYearAndMajor(year, major); // 查找目标节点
if (targetNode) {
deleteNode(targetNode); // 删除目标节点
printf("数据已删除。\n");
} else {
printf("未找到对应的数据。\n");
}
}
// 修改数据
void modifyData() {
char year[5];
char major[50];
printf("请输入要修改的年份:");
scanf("%s", year);
printf("请输入要修改的专业:");
scanf("%s", major);
Node* targetNode = findNodeByYearAndMajor(year, major); // 查找目标节点
if (targetNode) {
printf("请输入新的最高分:");
scanf("%d", &targetNode->data.max_score);
printf("请输入新的最低分:");
scanf("%d", &targetNode->data.min_score);
printf("请输入新的平均分:");
scanf("%f", &targetNode->data.avg_score);
printf("数据已修改。\n");
} else {
printf("未找到对应的数据。\n");
}
}
// 查询数据
void queryData() {
int choice;
displayQueryMenu(); // 显示查询菜单
scanf("%d", &choice);
switch (choice) {
case 1: {
char year[5];
printf("请输入年份:");
scanf("%s", year);
Node* current = findNodeByYear(year); // 根据年份查找节点
while (current) {
if (strcmp(current->data.year, year) == 0) {
displayData(current); // 显示节点数据
}
current = current->next;
}
break;
}
case 2: {
char year[5];
printf("请输入年份:");
scanf("%s", year);
Node* current = findNodeByYear(year); // 根据年份查找节点
int max_score = 0;
int min_score = 1000;
while (current) {
if (strcmp(current->data.year, year) == 0) {
if (current->data.max_score > max_score) max_score = current->data.max_score;
if (current->data.min_score < min_score) min_score = current->data.min_score;
}
current = current->next;
}
printf("最高分:%d\n", max_score);
printf("最低分:%d\n", min_score);
break;
}
case 3: {
char year[5];
int sortChoice;
printf("请输入年份:");
scanf("%s", year);
displaySortMenu(); // 显示排序菜单
scanf("%d", &sortChoice);
int size;
Node** nodeArray = createFilteredNodeArrayByYear(&size, year); // 创建筛选后的节点数组
if (size > 0) {
switch (sortChoice) {
case 1:
sortData(nodeArray, size, compareByMaxScoreAsc); // 按最高分升序排序
break;
case 2:
sortData(nodeArray, size, compareByMaxScoreDesc); // 按最高分降序排序
break;
case 3:
sortData(nodeArray, size, compareByMinScoreAsc); // 按最低分升序排序
break;
case 4:
sortData(nodeArray, size, compareByMinScoreDesc); // 按最低分降序排序
break;
case 5:
sortData(nodeArray, size, compareByAvgScoreAsc); // 按平均分升序排序
break;
case 6:
sortData(nodeArray, size, compareByAvgScoreDesc); // 按平均分降序排序
break;
default:
printf("无效的选择,请重新输入。\n");
free(nodeArray);
return;
}
for (int i = 0; i < size; i++) {
displayData(nodeArray[i]); // 显示排序后的数据
}
free(nodeArray);
} else {
printf("未找到对应的数据。\n");
}
break;
}
case 4: {
char major[50];
int sortChoice;
printf("请输入专业:");
scanf("%s", major);
displaySortMenu(); // 显示排序菜单
scanf("%d", &sortChoice);
int size;
Node** nodeArray = createFilteredNodeArrayByMajor(&size, major); // 创建筛选后的节点数组
if (size > 0) {
switch (sortChoice) {
case 1:
sortData(nodeArray, size, compareByMaxScoreAsc); // 按最高分升序排序
break;
case 2:
sortData(nodeArray, size, compareByMaxScoreDesc); // 按最高分降序排序
break;
case 3:
sortData(nodeArray, size, compareByMinScoreAsc); // 按最低分升序排序
break;
case 4:
sortData(nodeArray, size, compareByMinScoreDesc); // 按最低分降序排序
break;
case 5:
sortData(nodeArray, size, compareByAvgScoreAsc); // 按平均分升序排序
break;
case 6:
sortData(nodeArray, size, compareByAvgScoreDesc); // 按平均分降序排序
break;
default:
printf("无效的选择,请重新输入。\n");
free(nodeArray);
return;
}
for (int i = 0; i < size; i++) {
displayData(nodeArray[i]); // 显示排序后的数据
}
free(nodeArray);
} else {
printf("未找到对应的数据。\n");
}
break;
}
default:
printf("无效的选择,请重新输入。\n");
}
}
// 排序数据
void sortData(Node** array, int size, int (*cmp)(const void *, const void *)) {
qsort(array, size, sizeof(Node *), cmp); // 使用qsort函数排序
}
// 显示节点数据
void displayData(Node* n) {
if (n) {
printf("年份:%s, 科类:%s, 专业:%s, 批次:%s, 最高分:%d, 最低分:%d, 平均分:%.2f\n",
n->data.year, n->data.category, n->data.major, n->data.batch,
n->data.max_score, n->data.min_score, n->data.avg_score);
}
}
// 显示主菜单
void displayMenu() {
printf("\n--- 河北地质大学招生信息管理系统 ---\n");
printf("1. 增加数据\n");
printf("2. 删除数据\n");
printf("3. 修改数据\n");
printf("4. 查询数据\n");
printf("5. 保存并退出\n");
printf("请选择功能:");
}
// 显示查询菜单
void displayQueryMenu() {
printf("\n--- 查询功能 ---\n");
printf("1. 某年度所有专业的录取信息\n");
printf("2. 某年度所有专业录取的最高分和最低分\n");
printf("3. 根据某年度,所有专业的分别最高分,最低分和平均分按升序或降序显示\n");
printf("4. 根据某专业,不同年度的分别最高分,最低分和平均分按升序或降序显示\n");
printf("请选择功能:");
}
// 显示排序菜单
void displaySortMenu() {
printf("\n--- 排序功能 ---\n");
printf("1. 按最高分升序排列\n");
printf("2. 按最高分降序排列\n");
printf("3. 按最低分升序排列\n");
printf("4. 按最低分降序排列\n");
printf("5. 按平均分升序排列\n");
printf("6. 按平均分降序排列\n");
printf("请选择排序方式:");
}
// 创建新节点
Node* createNode(AdmissionInfo data) {
Node* newNode = (Node*)malloc(sizeof(Node));
if (newNode) {
newNode->data = data; // 赋值数据
newNode->next = NULL; // 初始化指针为空
}
return newNode;
}
// 根据年份查找节点
Node* findNodeByYear(char* year) {
Node* current = head;
Node* dummy = createNode((AdmissionInfo){"", "", "", "", 0, 0, 0.0});
Node* tail = dummy;
while (current) {
if (strcmp(current->data.year, year) == 0) {
Node* temp = createNode(current->data); // 创建临时节点
tail->next = temp; // 添加到结果链表
tail = temp; // 更新尾指针
}
current = current->next;
}
Node* result = dummy->next; // 结果链表的头节点
free(dummy);
return result;
}
// 根据年份和专业查找节点
Node* findNodeByYearAndMajor(char* year, char* major) {
Node* current = head;
while (current && (strcmp(current->data.year, year) != 0 || strcmp(current->data.major, major) != 0)) {
current = current->next;
}
return current;
}
// 插入节点
void insertNode(Node* newNode) {
if (!head) {
head = newNode; // 如果链表为空,将新节点作为头节点
} else {
Node* current = head;
while (current->next) {
current = current->next;
}
current->next = newNode; // 将新节点添加到链表末尾
}
}
// 删除节点
void deleteNode(Node* targetNode) {
if (head == targetNode) {
head = targetNode->next; // 如果是头节点,直接更新头指针
} else {
Node* current = head;
while (current->next && current->next != targetNode) {
current = current->next;
}
if (current->next) {
current->next = targetNode->next; // 将目标节点从链表中移除
}
}
free(targetNode); // 释放目标节点内存
}
// 创建节点数组
Node** createNodeArray(int *size) {
*size = 0;
Node* current = head;
while (current) {
(*size)++;
current = current->next;
}
Node** array = (Node **)malloc((*size) * sizeof(Node *)); // 分配数组内存
current = head;
for (int i = 0; i < *size; i++) {
array[i] = current;
current = current->next;
}
return array;
}
// 根据年份创建筛选后的节点数组
Node** createFilteredNodeArrayByYear(int *size, char* year) {
*size = 0;
Node* current = head;
Node** array = (Node **)malloc(MAX_PROF * sizeof(Node *));
while (current) {
if (strcmp(current->data.year, year) == 0) {
array[(*size)++] = current; // 添加符合条件的节点到数组
}
current = current->next;
}
return array;
}
// 根据专业创建筛选后的节点数组
Node** createFilteredNodeArrayByMajor(int *size, char* major) {
*size = 0;
Node* current = head;
Node** array = (Node **)malloc(MAX_PROF * sizeof(Node *));
while (current) {
if (strcmp(current->data.major, major) == 0) {
array[(*size)++] = current; // 添加符合条件的节点到数组
}
current = current->next;
}
return array;
}
// 按最高分升序比较
int compareByMaxScoreAsc(const void *a, const void *b) {
Node *nodeA = *(Node **)a;
Node *nodeB = *(Node **)b;
return (nodeA->data.max_score - nodeB->data.max_score);
}
// 按最高分降序比较
int compareByMaxScoreDesc(const void *a, const void *b) {
Node *nodeA = *(Node **)a;
Node *nodeB = *(Node **)b;
return (nodeB->data.max_score - nodeA->data.max_score);
}
// 按最低分升序比较
int compareByMinScoreAsc(const void *a, const void *b) {
Node *nodeA = *(Node **)a;
Node *nodeB = *(Node **)b;
return (nodeA->data.min_score - nodeB->data.min_score);
}
// 按最低分降序比较
int compareByMinScoreDesc(const void *a, const void *b) {
Node *nodeA = *(Node **)a;
Node *nodeB = *(Node **)b;
return (nodeB->data.min_score - nodeA->data.min_score);
}
// 按平均分升序比较
int compareByAvgScoreAsc(const void *a, const void *b) {
Node *nodeA = *(Node **)a;
Node *nodeB = *(Node **)b;
return (nodeA->data.avg_score > nodeB->data.avg_score) - (nodeA->data.avg_score < nodeB->data.avg_score);
}
// 按平均分降序比较
int compareByAvgScoreDesc(const void *a, const void *b) {
Node *nodeA = *(Node **)a;
Node *nodeB = *(Node **)b;
return (nodeA->data.avg_score < nodeB->data.avg_score) - (nodeA->data.avg_score > nodeB->data.avg_score);
}
6.2 数据score.scv文件
"年份","科类","专业","批次","最高分","最低分","平均分"
"2023","物理类","法学","本科提前批B","546","536","539.53"
"2023","物理类","工商管理类","本科提前批B","543","531","534.14"
"2023","物理类","计算机类","本科提前批B","569","545","552.60"
"2023","物理类","数学类","本科提前批B","562","527","534.60"
"2023","物理类","水利类","本科提前批B","531","522","524.90"
"2023","物理类","土木类","本科提前批B","531","521","523.80"
"2023","物理类","物流管理与工程类","本科提前批B","533","515","518.91"
"2023","物理类","休闲体育","本科提前批B","590","579","581.76"
"2023","历史类","法语","本科提前批B","521","511","515.25"
"2023","历史类","工商管理类","本科提前批B","540","526","530.00"
"2023","历史类","广告学","本科提前批B","534","512","518.75"
"2023","历史类","经济学类","本科提前批B","534","525","528.14"
"2023","历史类","休闲体育","本科提前批B","603","585","588.21"
"2023","物理类","材料类","本科批","521","508","514.09"
"2023","物理类","测绘类","本科批","528","510","512.36"
"2023","物理类","城乡规划","本科批","519","508","510.85"
"2023","物理类","大数据管理与应用","本科批","539","535","536.65"
"2023","物理类","地理信息科学","本科批","533","524","526.11"
"2023","物理类","地球物理学","本科批","521","509","512.59"
"2023","物理类","地质工程","本科批","534","512","515.93"
"2023","物理类","地质类","本科批","547","506","509.75"
"2023","物理类","法学","本科批","560","549","552.47"
"2023","物理类","防灾减灾科学与工程","本科批","538","515","521.23"
"2023","物理类","工商管理类","本科批","546","541","542.96"
"2023","物理类","工商管理类","本科批","534","514","524.29"
"2023","物理类","公共管理类","本科批","537","516","520.62"
"2023","物理类","管理科学与工程类","本科批","537","516","519.96"
"2023","物理类","环境工程","本科批","524","512","514.77"
"2023","物理类","计算机科学与技术 ","本科批","550","514","525.37"
"2023","物理类","计算机类","本科批","552","539","541.43"
"2023","物理类","金融学","本科批","524","510","515.80"
"2023","物理类","经济学类","本科批","543","526","532.79"
"2023","物理类","勘查技术与工程","本科批","550","508","511.93"
"2023","物理类","旅游地学与规划工程","本科批","526","506","511.20"
"2023","物理类","数学类","本科批","537","523","526.71"
"2023","物理类","水利类","本科批","558","517","524.97"
"2023","物理类","土地资源管理","本科批","519","507","510.37"
"2023","物理类","土木类","本科批","529","516","519.11"
"2023","物理类","物流管理与工程类","本科批","529","516","520.00"
"2023","物理类","英语","本科批","544","534","537.12"
"2023","物理类","资源环境大数据工程","本科批","529","516","520.58"
"2023","历史类","法学","本科批","561","551","554.71"
"2023","历史类","法语","本科批","538","519","529.00"
"2023","历史类","公共管理类","本科批","544","521","525.89"
"2023","历史类","广告学","本科批","539","526","530.25"
"2023","历史类","汉语国际教育","本科批","544","536","538.79"
"2023","历史类","金融学","本科批","522","508","512.36"
"2023","历史类","经济学类","本科批","547","527","535.21"
"2023","历史类","物流管理与工程类","本科批","530","513","516.98"
"2023","历史类","英语","本科批","551","527","537.00"
"2023","艺术类","产品设计","本科提前批B","558","545","546.77"
"2023","艺术类","设计学类","本科提前批B","557","547","548.81"
"2023","艺术类","书法学","本科提前批B","589","579","583.70"
"2022","历史类","法学","本科批","554","546","548.75"
"2022","历史类","法语","本科批","542","535","537.17"
"2022","历史类","法语","本科提前批B","545","527","532.20"
"2022","历史类","工商管理类","本科批","550","544","545.68"
"2022","历史类","工商管理类","本科提前批B","538","528","530.61"
"2022","历史类","工商管理类","本科提前批","344","340","342.00"
"2022","历史类","工商管理类","地方专项","544","533","535.70"
"2022","历史类","工商管理类","本科批","545","533","536.38"
"2022","历史类","公共管理类","本科批","547","533","536.25"
"2022","历史类","广告学","本科批","553","541","542.78"
"2022","历史类","广告学","本科提前批B","540","528","532.88"
"2022","历史类","汉语国际教育","本科批","549","543","544.43"
"2022","历史类","捷克语","本科批","529","517","520.44"
"2022","历史类","金融学","本科批","530","519","523.89"
"2022","历史类","经济学类","本科批","553","541","542.46"
"2022","历史类","经济学类","地方专项","545","536","539.60"
"2022","历史类","经济学类","本科提前批B","544","535","538.36"
"2022","历史类","物流管理与工程类","本科批","538","524","527.29"
"2022","历史类","英语","本科批","551","546","547.79"
"2022","历史类","英语","地方专项","544","539","540.30"
"2022","物理类","材料类","本科批","514","510","511.95"
"2022","物理类","材料类","地方专项","511","507","508.57"
"2022","物理类","测绘类","本科批","520","508","509.88"
"2022","物理类","城乡规划","本科批","525","509","511.94"
"2022","物理类","大数据管理与应用","本科批","532","526","527.43"
"2022","物理类","地理信息科学","本科批","532","519","522.56"
"2022","物理类","地球物理学","本科批","543","507","510.88"
"2022","物理类","地质工程","地方专项","513","509","510.38"
"2022","物理类","地质工程","本科批","525","507","509.81"
"2022","物理类","地质类","本科批","528","505","508.65"
"2022","物理类","地质类","地方专项","515","502","506.93"
"2022","物理类","法学","本科批","548","532","534.48"
"2022","物理类","法学","本科提前批B","535","526","529.23"
"2022","物理类","工商管理类","本科批","542","534","536.53"
"2022","物理类","工商管理类","本科提前批B","531","525","526.91"
"2022","物理类","工商管理类","本科提前批","401","381","391.00"
"2022","物理类","工商管理类","本科批","556","524","528.00"
"2022","物理类","工商管理类","地方专项","530","521","523.40"
"2022","物理类","公共管理类","本科批","525","516","518.08"
"2022","物理类","管理科学与工程类","本科批","522","514","516.19"
"2022","物理类","环境工程","本科批","525","512","514.59"
"2022","物理类","计算机类","本科提前批B","589","536","544.10"
"2022","物理类","计算机类","地方专项","539","535","536.13"
"2022","物理类","计算机类","本科批","544","529","531.23"
"2022","物理类","金融学","本科批","535","510","515.40"
"2022","物理类","经济学类","本科批","535","527","529.66"
"2022","物理类","经济学类","地方专项","536","526","528.67"
"2022","物理类","勘查技术与工程","本科批","513","504","506.47"
"2022","物理类","旅游地学与规划工程","本科批","512","503","506.20"
"2022","物理类","数学类","本科提前批B","533","521","526.46"
"2022","物理类","数学类","本科批","532","515","518.27"
"2022","物理类","水利类","本科提前批B","526","517","520.60"
"2022","物理类","水利类","本科批","532","514","517.70"
"2022","物理类","水利类","地方专项","517","513","515.14"
"2022","物理类","土地资源管理","本科批","526","507","510.60"
"2022","物理类","土木类","本科提前批B","536","519","524.40"
"2022","物理类","土木类","本科批","528","515","516.85"
"2022","物理类","物流管理与工程类","本科批","524","516","517.50"
"2022","物理类","物流管理与工程类","本科提前批B","531","515","519.00"
"2022","物理类","英语","本科批","540","533","535.20"
"2022","艺术类","播音与主持艺术","本科提前批B","513","501","504.56"
"2022","艺术类","产品设计","本科提前批B","549","542","543.26"
"2022","艺术类","广播电视编导","本科提前批B","521","504","507.03"
"2022","艺术类","设计学类","本科提前批B","557","544","545.06"
"2022","艺术类","影视摄影与制作","本科提前批B","544","537","538.83"
"2021","艺术类","广播电视编导","本科提前批B","501","485","488.56"
"2021","艺术类","播音与主持艺术","本科提前批B","515","503","507.22"
"2021","艺术类","设计学类","本科提前批B","550","538","540.21"
"2021","艺术类","书法学","本科提前批B","584","572","576.15"
"2021","艺术类","影视摄影与制作","本科提前批B","561","533","536.01"
"2021","物理类","法学","本科提前批B","541","528","532.77"
"2021","历史类","法语","本科提前批B","547","538","543.40"
"2021","物理类","工商管理类","本科提前批B","543","529","532.60"
"2021","历史类","工商管理类","本科提前批B","554","542","545.89"
"2021","历史类","广告学","本科提前批B","550","538","541.60"
"2021","物理类","计算机类","本科提前批B","564","538","544.70"
"2021","历史类","经济学类","本科提前批B","553","547","548.90"
"2021","物理类","数学类","本科提前批B","543","529","533.15"
"2021","物理类","水利类","本科提前批B","568","522","533.70"
"2021","物理类","土木类","本科提前批B","543","524","530.00"
"2021","物理类","物流管理与工程类","本科提前批B","527","521","522.85"
6.3 运行结果
(1)查询数据
①查询某年度所有专业的录取信息
例:查询2021年所有专业的录取信息
图 3查询2021年所有专业的录取信息
②查询某年度所有专业录取的最高分和最低分
例:查询2021年所有专业录取的最高分和最低分
图 4 查询2021年所有专业录取的最高分和最低分
③根据某年度,所有专业的最高分,最低分和平均分按升序或降序显示
例:查询2021年所有专业按最高分升序排序
图 5 查询2021年所有专业按最高分升序排序
④根据某专业,不同年度的最高分,最低分和平均分按升序或降序显示
例:查询计算机类所有年度按平均分升序排序
图 6 查询计算机类所有年度按平均分升序排序
(2)增加数据
例:增加数据:2021-物理类-软件工程-本科批-560-550-555
图 7 增加信息
(3)修改信息
例:将2021年软件工程分数修改为565-555-560
图 8 修改信息
(4)删除信息
例:删除软件工程专业信息
图 9 删除信息
7 实验总结
本次实验设计并实现了河北地质大学招生信息管理系统,通过C语言编程实现了招生信息的增加、删除、修改和查询功能,并利用文件读写操作实现了数据的持久化存储。
(1)实验过程:
①设计数据结构: 首先设计了招生信息的数据结构,选择了结构体来表示每个招生信息的属性,并利用链表来存储多个招生信息。
②文件操作: 使用了C标准库中的文件读写函数,将招生信息保存在.csv文件中,以逗号分隔各字段,实现了数据的持久化存储。
③功能实现: 通过编写各种函数,实现了新增数据、删除数据、修改数据和查询数据等基本功能,并尽量减少全局变量的使用,采用函数参数传递数据。
④用户界面: 设计了简单的菜单和交互提示,使用户可以方便地选择所需功能,并根据提示输入相关信息。
⑤代码规范和注释: 在编写代码时,注重代码规范性和可读性,采用了清晰的命名和适当的注释,使代码易于理解和维护。
(2)实验结果:
①实现了招生信息的增加、删除、修改和查询功能,用户可以通过简单的操作完成对招生信息的管理。
②数据能够持久化存储,保存在.csv文件中,保证了数据的安全性和可靠性。
③用户界面友好,提供了清晰的菜单和交互提示,使用户操作简单明了。
(3)实验收获:
①通过本次实验,加深了对C语言程序设计的理解,掌握了结构体、链表和文件操作等重要概念和技能。
②锻炼了问题分析和解决能力,在设计和实现功能时,遇到了一些问题,通过查找资料和思考解决了这些问题。
③提高了编程规范意识和代码质量,编写代码时更加注重了命名规范、代码风格和注释的书写。
(4)可改进之处:
①可进一步优化程序性能,例如在文件操作和数据查询方面采用更加高效的算法。
②可添加更多功能,如数据统计、排序功能等,提升系统的实用性和完整性。
③可以增加错误处理机制,增强程序的健壮性,使其能够更好地处理异常情况。
(5)对未来的展望:
通过本次实验,不仅掌握了C语言编程技巧,还对软件开发过程有了更深入的了解,未来可以进一步学习其他编程语言和软件开发技术,提升自己的技能水平,为更复杂的项目开发打下坚实的基础。