一、设计内容
学生管理系统,是用c语言程序设计的一款简便软件项目,能对学生信息进行增删查改、排序、导入、导出,使用链表的结构存储。
二、功能需求
1.学生信息批量录入;
2.查询所有学生信息;
3.通过学号删除学生信息;
4.通过学号、姓名查询学生信息;
5.通过学号修改学生信息;
6.在表中某个位置插入学生信息;
7.导出学生信息文件;
8、导入学生信息表;
9.按学号、年龄排序;
三、单链表数据结构定义
// 存储学生的链表
typedef struct //定义每个人员信息结构体
{
long int number; //学号
char name[50]; //姓名
int age; //年龄
char sex[20]; //性别
char birthday[50]; // 出生年月
char addres[50]; //地址
char phoneNum[50]; //电话
char email[40]; // 邮箱
} DataType;
typedef struct link_stu // 定义链表
{
DataType stuInfo;
struct link_stu *next; // 指向下一个学生数据
} ListNode;
四、系统功能模块
1.创建学生表批量录入学生信息
ListNode *create()
{
int i;
ListNode *s, *r, *Ls = (ListNode *)malloc(sizeof(ListNode));
Ls->next = NULL;
r = Ls; //尾节点
printf("请输入学生人数:");
scanf("%d", &num);
for (i = 1; i <= num; i++)
{
s = (ListNode *)malloc(sizeof(ListNode)); // 新建学生结点
printf("请输入第%d个学生\n", i);
printf("学号:");
scanf("%ld", &s->stuInfo.number);
printf("姓名:");
scanf("%s", &s->stuInfo.name);
printf("年龄:");
scanf("%d", &s->stuInfo.age);
printf("性别:");
scanf("%s", &s->stuInfo.sex);
printf("出生年月:");
scanf("%s", &s->stuInfo.birthday);
printf("地址:");
scanf("%s", &s->stuInfo.addres);
printf("电话:");
scanf("%s", &s->stuInfo.phoneNum);
printf("邮箱:");
scanf("%s", &s->stuInfo.email);
s->next = Ls->next;
Ls->next = s;
}
printf("录入结束,请按任意键结束!\n");
getch();
return Ls;
}
2.查询所有学生信息
// 查询所有学生信息
void searchAll(ListNode *L)
{
ListNode *p = L->next;
if (p == NULL)
{
printf("学生表为空,请先创建学生表,按任意键继续!\n");
getch();
}
else
{
printf("———————————————————所有学生信息———————————————————————————————————————————\n");
printf("| 学号 姓名 年龄 性别 出生年月 地址 电话 邮箱 |\n");
printf("————————————————————————————————————————————————————————————————————————\n");
while (p != NULL)
{
printf("%6ld %6s %5d %5s %9s %9s %9s %9s\n", p->stuInfo.number, p->stuInfo.name, p->stuInfo.age,
p->stuInfo.sex, p->stuInfo.birthday, p->stuInfo.addres, p->stuInfo.phoneNum,p->stuInfo.email);
p = p->next;
}
printf("显示结束,请按任意键继续!\n");
getch();
}
}
3.通过学号删除学生信息
//根据学号删除学生信息
ListNode *deleNode(ListNode *head)
{
ListNode *v1, *v2;
long number;
if (head == NULL)
{
printf("您操作的通讯录此时为空,不能进行删除操作!");
}
printf("请输入要删除的学生的学号:");
scanf("%ld", &number);
for (v2 = v1 = head; v1 != NULL;)
{
if (v1->stuInfo.number == number)
{
if (head->stuInfo.number == number) //对头指针特殊处理
{
v1 = head;
head = head->next;
free(v1);
printf("该学生已成功删除!\n");
v2 = v1 = head;
return head;
}
else
{
v2->next = v1->next;
free(v1);
v1 = v2->next;
printf("该学生已成功删除!\n");
return head;
}
}
else
{
v2 = v1;
v1 = v1->next;
}
}
printf("你要删除的学生不存在\n\n");
return head;
}
4.通过学号、姓名查询学生信息
// 根据学号、姓名查询学生信息
void seleById(ListNode *head_linkman)
{
ListNode *p1, *p2;
char name[20];
long number;
int nM, num;
if (head_linkman == NULL)
{
printf("您操作的学生表此时为空,不能进行查询操作!");
}
p1 = head_linkman;
nM = 0;
if (p1 != NULL)
{
printf("1.选择学号查询\n");
printf("2.选择姓名查询\n");
printf("请输入查询方式:\n");
scanf("%d", &num);
if (num == 1)
{
printf("请输入要查询的学生的学号:");
scanf("%ld", &number);
}
else if (num == 2)
{
printf("请输入要查询的学生的姓名:");
scanf("%s", &name);
}
else
{
printf("输入无效!!");
}
while (p1->stuInfo.number != number && p1->next != NULL)
{
p1 = p1->next;
}
if (p1->stuInfo.number == number || strcmp(p1->stuInfo.name, name) == 0)
{
nM++;
printf("———————————————————所有学生信息———————————————————————————————————————————\n");
printf("| 学号 姓名 年龄 性别 出生年月 地址 电话 邮箱 |\n");
printf("————————————————————————————————————————————————————————————————————————\n");
printf("%6ld %6s %5d %5s %9s %9s %9s %9s\n", p1->stuInfo.number, p1->stuInfo.name, p1->stuInfo.age,
p1->stuInfo.sex, p1->stuInfo.birthday, p1->stuInfo.addres, p1->stuInfo.phoneNum,p1->stuInfo.email);
}
if (nM == 0)
{
printf("该学生未录入!\n");
}
printf("显示结束,请按任意键继续!\n");
getch();
}
}
5.通过学号修改学生信息
// 根据学号修改学生信息
void updata(ListNode *L)
{
ListNode *p;
long number;
int nM;
if (L == NULL)
{
printf("您操作的学生表此时为空,不能进行修改操作!");
}
p = L;
if (p != NULL)
{
printf("请输入要修改的学生的学号:");
scanf("%ld", &number);
while (p->stuInfo.number != number && p->next != NULL)
{
p = p->next;
}
if (p->stuInfo.number == number)
{
printf("姓名:");
scanf("%s", &p->stuInfo.name);
printf("年龄:");
scanf("%d", &p->stuInfo.age);
printf("性别:");
scanf("%s", &p->stuInfo.sex);
printf("出生年月:");
scanf("%s", &p->stuInfo.birthday);
printf("地址:");
scanf("%s", &p->stuInfo.addres);
printf("电话:");
scanf("%s", &p->stuInfo.phoneNum);
printf("邮箱:");
scanf("%s", &p->stuInfo.email);
printf("修改成功!\n");
}
printf("显示结束,请按任意键继续!\n");
getch();
}
}
6.查找第i个节点的存放地址
// 查找第i个节点的存放地址
ListNode *find(ListNode *head, int i)
{
int j = 0;
ListNode *p = head;
if (i < 0)
{
printf("\n带头结点的单链表中不存在第%d个结点!\n", i);
return NULL;
}
else if (i == 0)
return p; /*此时p指向的是头结点*/
while (p && i != j) /*没有查找完并且还没有找到*/
{
p = p->next;
j++; /*继续向后(左)查找,计数器加1*/
}
return p; /*返回结果,i=0时,p指示的是头结点*/
}
7.表中某个位置插入学生信息
// 在第i个结点新增学生信息
ListNode *insert(ListNode *head)
{
int i;
printf("请输入学生要插入位置:");
scanf("%d", &i);
ListNode *p, *q;
q = find(head, i - 1); /*查找带头结点的单链表中的第i个结点*/
/*i=0,表示新结点插入在头结点之后,此时q指向的是头结点*/
if (!q) /*没有找到*/
{
printf("\n带头结点的单链表中不存在第%d个结点!不能插入!\n", i);
return head;
}
p = (ListNode *)malloc(sizeof(ListNode)); /*为准备插入的新结点分配空间*/
printf("请输入要插入位置%d学生信息\n", i);
printf("学号:");
scanf("%ld", &p->stuInfo.number);
printf("姓名:");
scanf("%s", &p->stuInfo.name);
printf("年龄:");
scanf("%d", &p->stuInfo.age);
printf("性别:");
scanf("%s", &p->stuInfo.sex);
printf("出生年月:");
scanf("%s", &p->stuInfo.birthday);
printf("地址:");
scanf("%s", &p->stuInfo.addres);
printf("电话:");
scanf("%s", &p->stuInfo.phoneNum);
printf("邮箱:");
scanf("%s", &p->stuInfo.email);
p->next = q->next; /*插入(1)*/
q->next = p; /*插入(2),当i=0时,由于q指向的是头结点,本语句等价于head>next=p */
return head;
}
8.导出学生信息表文件
// 保存文件
void save(ListNode *hd)
{
if (hd == NULL)
{
printf("链表为空,不能保存文件,请按任意键继续!\n");
getch();
}
else
{
char filename[15];
char type[] = ".txt";
char all[15];
printf("请输入保存的文件名:");
scanf("%s",filename);
strcpy(all,filename);
strcat(all,type);
FILE *fp = fopen(all, "w");
ListNode *p = hd->next;
while (p != NULL)
{
fprintf(fp, "%ld %s %d %s %s %s %s %s\n", p->stuInfo.number, p->stuInfo.name, p->stuInfo.age, p->stuInfo.sex,
p->stuInfo.birthday, p->stuInfo.addres, p->stuInfo.phoneNum, p->stuInfo.email);
p = p->next;
}
fclose(fp);
printf("链表保存结束,请按任意键继续!\n");
getch();
}
}
9.导入学生信息表
// 导入学生数据
ListNode *loadFile(ListNode *head)
{
long int number; //学号
char name[50]; //姓名
int age; //年龄
char sex[20]; //性别
char birthday[50]; // 出生年月
char addres[50]; //地址
char phoneNum[50]; //电话
char email[40]; // 邮箱
FILE *fp;
char filename[15];
char type[] = ".txt";
char all[15];
printf("请输入保存的文件名:");
scanf("%s",filename);
strcpy(all,filename);
strcat(all,type);
if ((fp = fopen(all, "r")) == NULL)
{
printf("文件打开失败!\n");
return head;
}
if (head == NULL || head->next == NULL)
{ // 如果链表为空
head = (ListNode *)malloc(sizeof(ListNode)); // 创建一个头结点
head->next = NULL;
}
ListNode *tail = head;
while (tail->next != NULL)
{
tail = tail->next;
}
while (fscanf(fp, "%ld%s%d%s%s%s%s%s", &number, name, &age, sex, birthday, addres, phoneNum, email) != EOF)
{
ListNode *newNode = (ListNode *)malloc(sizeof(ListNode));
newNode->stuInfo.number = number;
strcpy(newNode->stuInfo.name, name);
newNode->stuInfo.age = age;
strcpy(newNode->stuInfo.sex, sex);
strcpy(newNode->stuInfo.birthday, birthday);
strcpy(newNode->stuInfo.addres, addres);
strcpy(newNode->stuInfo.phoneNum, phoneNum);
strcpy(newNode->stuInfo.email, email);
newNode->next = NULL;
if (tail == NULL)
{ // 如果链表为空,则将新节点作为头节点
tail = newNode;
head->next = tail;
}
else
{
tail->next = newNode;
tail = newNode;
}
}
fclose(fp);
printf("导入数据成功,请按任意键继续!\n");
getch();
return head;
}
10.按学号、年龄排序文章来源:https://www.toymoban.com/news/detail-784077.html
// 按学号或年龄排序
ListNode *Sort(ListNode *mylist, int num)
{
if ((mylist->next == NULL) || (mylist->next->next == NULL))
{
return NULL;
}
ListNode *head, *pre, *cur, *next, *end, *temp;
head = mylist;
end = NULL;
//从链表头开始将较大值往后沉
while (head->next != end)
{
for (pre = head, cur = pre->next, next = cur->next; next != end; pre = pre->next, cur = cur->next, next = next->next)
{
if (num == 1)
{ // num=1时按学号排序
//相邻的节点比较
if (cur->stuInfo.number > next->stuInfo.number)
{
cur->next = next->next;
pre->next = next;
next->next = cur;
temp = next;
next = cur;
cur = temp;
}
}
if (num == 2)
{
if (cur->stuInfo.age > next->stuInfo.age)
{
cur->next = next->next;
pre->next = next;
next->next = cur;
temp = next;
next = cur;
cur = temp;
}
}
}
end = cur;
}
return mylist;
}
- 主函数调用
void prin()
{
printf("=====================================欢迎使用学生管理系统===============================\n");
printf("|| 1.创建学生表批量录入学生信息 ||\n");
printf("|| 2.查询所有学生信息 ||\n");
printf("|| 3.通过学号删除学生信息 ||\n");
printf("|| 4.通过学号、姓名查询学生信息 ||\n");
printf("|| 5.通过学号修改学生信息 ||\n");
printf("|| 6.表中某个位置插入学生信息 ||\n");
printf("|| 7.导出学生信息表文件 ||\n");
printf("|| 8.导入学生信息表 ||\n");
printf("|| 9.按学号、年龄排序 ||\n");
printf("|| 10.退出系统! ||\n");
printf("========================================================================================\n");
printf("请选择你的功能:");
}
void main()
{
ListNode *ls = NULL;
int number, num;
while (1)
{
prin();
scanf("%d", &number);
switch (number)
{
case 1: // 创建学生表批量录入学生信息
ls = create();
break;
case 2: // 查询所有学生信息
if (ls)
{
searchAll(ls);
break;
}
else
{
printf("学生表为空,请先创建学生表,按任意键继续!\n");
break;
}
case 3: // 通过学号删除学生信息
if (ls)
{
ls = deleNode(ls);
break;
}
else
{
printf("学生表为空,请先创建学生表,按任意键继续!\n");
break;
}
case 4: // 通过学号查询学生信息
seleById(ls);
break;
case 5: // 通过学号修改学生信息;
if (ls)
{
updata(ls);
break;
}
else
{
printf("学生表为空,请先创建学生表,按任意键继续!\n");
break;
}
case 6: // 第i个结点新增学生信息);
if (ls)
{
ls = insert(ls);
break;
}
else
{
printf("学生表为空,请先创建学生表,按任意键继续!\n");
break;
}
case 7: // 导出文件
save(ls);
break;
case 8: // 导入文件
ls = loadFile(ls);
break;
case 9:
if(ls) {
printf("===========================================\n");
printf("1.按学号进行排序\n");
printf("2.按年龄进行排序\n");
printf("请选择排序的方式\n");
scanf("%d", &num);
ls = Sort(ls, num);
printf("=================排序后的学生信息=================\n");
searchAll(ls);
break;
} else {
printf("学生表为空,请先创建学生表,按任意键继续!\n");
break;
}
case 10: // 退出系统!
printf("退出系统!");
exit(0);
default:
break;
}
}
}
Tip:该系统是数据库结构基于C语言的一个课堂实训有很多不足之处,看到这的小伙伴请自己注意哦!
文章来源地址https://www.toymoban.com/news/detail-784077.html
到了这里,关于学生管理系统——C语言单链表结构存储的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!