欢迎交流,共同进步。
题目为:学生信息管理系统
使用双链表机制,实现功能如下:插入一个学生数据、删除一个学生数据、修改一个学生数据、查找一个学生数据、遍历显示学生数据、导入表格数据、导出表格数据 。
#include<stdio.h> //标准IO
#include<stdlib.h> //标准库
#include<string.h> //字符串函数
#include<stdbool.h>
struct student
{
int num; //学号
float score; //分数
struct student *prev; //前指针
struct student *next; //后指针
};
typedef struct student student_t;
char path[] = "C:\\Users\\AD\\Desktop";
student_t* initnode(void); //初始化链表
student_t* createnode(int num, float score); //创建节点,输出此节点指针
int showmenu(void); //显示目录
void shownode(student_t* p); //显示节点数据
void travenode(student_t* header); //轮询显示节点数据
void insertexcel(student_t* header); //导入数据表格
void exportexcel(student_t* header); //导出数据表格
void deletenode(student_t* header, int num); //按学号删除节点
int inputdata(int* num, float* score, int flag); //数据输入 ,1 一个有效数据 2 两个有效数据
void insertnode(student_t* header,student_t* newnode,bool flag); //插入节点,0 头插 1尾插
void modifynode_or_findnode(student_t* header, int num, float score, int flag); //1 修改学分 2 查找数据
int main(void)
{
student_t *Header = initnode();
int num = 0 ; //学号
float score = 0 ; //分数
while (1)
{
switch (showmenu())
{
case 1 : //插入一个学生数据
if(inputdata(&num, &score,2) == 1)
{
insertnode(Header, createnode(num, score),true);
}
break;
case 2: //删除一个学生数据
if (inputdata(&num, &score, 1) == 1)
{
deletenode(Header, num);
}
break;
case 3: //修改一个学生数据
if (inputdata(&num, &score, 2) == 1)
{
modifynode_or_findnode(Header, num, score,1);
}
break;
case 4: //查找一个学生数据
if (inputdata(&num, &score, 1) == 1)
{
modifynode_or_findnode(Header, num, score, 2);
}
break;
case 5: //遍历显示学生数据
travenode(Header);
break;
case 6: //导入表格数据
insertexcel(Header);
break;
case 7: //导出表格数据
exportexcel(Header);
break;
case 8: //退出系统
exit(0);
break;
default:
printf("输入错误\n\n");
break;
}
}
return 0;
}
//初始化列表
student_t *initnode(void)
{
return createnode(0, 0);
}
//显示节点数据
void shownode(student_t *p)
{
printf("\nnum = %d ," , p->num );
printf("score = %.1f ," , p->score);
printf("node = %p ," , p);
printf("node->perv = %p ," , p->prev );
printf("node->next = %p .\n" , p->next );
}
//显示菜单数据
int showmenu(void)
{
int num = 0 ;
printf("菜单:\n");
printf("\033[47;31m插入一个学生数据:1\033[0m\n");
printf("删除一个学生数据:2\n");
printf("修改一个学生数据:3\n");
printf("查找一个学生数据:4\n");
printf("遍历显示学生数据:5\n");
printf("导入表格数据 :6\n");
printf("导出表格数据 :7\n");
printf("退出系统 :8\n");
printf("请输入:");
scanf_s("%d", &num);
return num;
}
//遍历显示数据
void travenode(student_t* header)
{
student_t* node = header;
while (node->next != NULL)
{
node = node->next;
shownode(node);
}
printf("显示完成!\n\n");
}
//输入数据
int inputdata(int *num ,float *score,int flag)
{
int cnt = 0;
while (cnt != 4)
{
if (flag == 2)
{
printf("\n请输入学号、分数(中间使用空格分开):");
scanf_s("%d %f", num, score);
if (((*num) >= 1000) || ((*num) < 0) || ((*score) > 100) || ((*score) < 0))
printf("\n输入越界,请重新输入\n");
else
return 1;
}
else if(flag == 1)
{
printf("\n请输入学号:");
scanf_s("%d", num);
if (((*num) >= 1000) || ((*num) < 0))
printf("\n输入越界,请重新输入\n");
else
return 1;
}
cnt++;
}
return 0;
}
//创建一个节点
student_t* createnode(int num,float score)
{
student_t* node = NULL;
node = (student_t*)malloc(sizeof(student_t));
if (node == NULL)
{
printf("input fair\n");
return node;
}
memset(node, 0, sizeof(student_t));
node->num = num;
node->score = score;
node->prev = NULL;
node->next = NULL;
return node;
}
//双链表插入
void insertnode(student_t* header, student_t* newnode, bool flag)
{
student_t* node = header;
while (node->next != NULL)
{
node = node->next;
if ((newnode->num == node->num))
{
printf("该学号已存在!\n\n");
return;
}
}
if (node->next == NULL)
{
newnode->next = node->next;
newnode->prev = node;
node->next = newnode;
printf("插入成功!\n\n");
return;
}
if (flag == false)
{
newnode->next = node->next;
newnode->prev = node;
node->next->prev = newnode;
node->next = newnode;
}
else
{
while (NULL != node->next)
{
node = node->next;
}
newnode->next = node->next;
newnode->prev = node;
node->next = newnode;
}
printf("\n插入成功!\n\n");
}
//双链表删除节点
void deletenode(student_t* header, int num)
{
student_t* node =header;
while ( NULL != node->next)
{
node = node->next;
if (num == node->num)
{
if (node->next == NULL)
{
node->prev->next = NULL;
free(node);
}
else
{
node->prev->next = node->next;
node->next->prev = node->prev;
free(node);
}
printf("完成删除\n\n");
return;
}
}
printf("没有找到对应要删除的学号,或者该学号已经被删除!\n\n");
}
//学分修改,查找数据
void modifynode_or_findnode(student_t* header, int num,float score , int flag)
{
student_t* node = header;
while (NULL != node->next)
{
node = node->next;
if (num == node->num)
{
if (flag == 1)
{
node->score = score;
printf("完成修改\n\n");
return;
}
else if (flag == 2)
{
shownode(node);
printf("\n\n");
return;
}
}
}
printf("没有找到对应的学号,或者该学号已经被删除!\n\n");
}
//导入表格数据
void insertexcel(student_t* header)
{
FILE* fp;
student_t* node = NULL;
char filename[100], buffer[100];
int num = 0;
int data_num[1000] = { 0 };
float data_score[1000] = { 0 };
printf("\n输入文件名: ");
scanf("%99s", filename);
sprintf(filename, "%s.csv", filename);
printf("\n输入学生数: ");
scanf_s("%d", &num);
sprintf(buffer, "%s\\%s", path, filename);
if ((fp = fopen(buffer, "r")) == NULL)
{
printf("路径无效,导入失败\n\n");
return;
}
fseek(fp, 9L, SEEK_SET); // 从文件第二行开始读取
for (int i = 0; i < num; i++)
{
fscanf_s(fp, "%d",&data_num[i]);
fseek(fp, 1L, SEEK_CUR); //fp指针从当前位置向后移动
fscanf_s(fp, "%f",&data_score[i]);
fseek(fp, 1L, SEEK_CUR); //fp指针从当前位置向后移动
if (((data_num[i]) >= 1000) || ((data_num[i]) < 0) || ((data_score[i]) > 100) || ((data_score[i]) < 0))
{
printf("\n输入越界,学号%d\n", data_num[i]);
continue;
}
node = createnode(data_num[i], data_score[i]);
insertnode(header, node, true);
}
fclose(fp);
printf("导入完成\n\n");
}
//导出表格数据
void exportexcel(student_t* header)
{
FILE* fp;
student_t* node = header;
char filename[20], buffer[40];
int num = 0;
int data_num[1000] = { 0 };
float data_score[1000] = { 0 };
printf("\n输入文件名: ");
scanf("%99s", filename);
sprintf(filename, "%s.csv", filename);
sprintf(buffer, "%s\\%s", path, filename);
if ((fp = fopen(buffer, "w")) == NULL)
{
printf("路径无效, 导出失败\n\n");
return;
}
fprintf(fp, "学分,学号\n");
while (NULL != node->next)
{
node = node->next;
fprintf(fp, "%d,%.1f\n", node->num,node->score);
}
fclose(fp);
printf("导出完成\n\n");
}
···