//main.c函数
#include "stdio.h"
#include "caozuo.h"
#pragma warning(disable:4996)
int main()
{
STUDENT * SL=NULL;//学生信息链表
char xm[20];
//菜单
printf(" **************学生成绩管理系统**************\n");
printf(" *1.添加学生信息 *\n");
printf(" *2.删除学生信息 *\n");
printf(" *3.修改学生信息 *\n");
printf(" *4.浏览学生信息 *\n");
printf(" *5.保存学生信息 *\n");
printf(" *6.打开文件 *\n");
printf(" *7.排序学生信息(以手机号码) *\n");
printf(" *0.退出程序 *\n");
printf(" ********************************************\n");
printf(" \n");
printf("请选择: ");
//等待用户的输入确认
int M,T;
char z;
M=getchar();
T=getchar();
while(M!='0')
{
switch(M)
{
case '1':
SL=TianJia(SL);
break;
case '2':
printf("请输入要删除的学生信息:");
gets(xm);
SL=ShanChu(SL,xm);
break;
case '3':
printf("请输入要修改的学生信息:");
gets(xm);
SL=XiuGai(SL,xm);
break;
case '4':printf("进入浏览学生信息的界面。\n");
LiuLan(SL);
break;
case '5':
BAOCUN(SL);
break;
case '6':
SL=DaKai(SL);
break;
case '7':
sort(SL);
break;
case '0':break;
}
//显示菜单
printf("按任意键继续");
getchar();
system("cls");//本函数实现清屏的功能
printf("1.添加学生信息\n");
printf("2.删除学生信息\n");
printf("3.修改学生信息\n");
printf("4.浏览学生信息\n");
printf("5.保存学生信息\n");
printf("6.打开文件\n");
printf("7.排序学生信息\n");
printf("0.退出程序\n");
M=getchar();
T=getchar();
}
}
//student.h头文件
typedef struct date
{
int year;
int month;
int day;
}DATE;
//姓名、性别、民族、出生日期、班级、地址、手机号码、宿舍
typedef struct student
{
char xm[20];
char xb[10];
char mz[15];
DATE csrq;
char bj[20];
char dz[50];
char sj[15];
char ss[14];
struct student *next;
}STUDENT;
struct student *head;
//caozuo.h
#include "stdio.h"
#include "student.h"
#include "stdlib.h"
#include "string.h"
#pragma warning(disable:4996)
/*
SL:学生信息组成的单链表
newStudent:需要加入进来的新的学生结点
*/
STUDENT* tianjiaxuesheng(STUDENT* SL, STUDENT* newStudent)
{
STUDENT* p1, * p2;
//判断链接 SL是否 为空。
if (SL == NULL)
{
SL = newStudent;
newStudent->next = NULL;//将新加入结点的指针域,设置为NULL
}
else
{
//定位链表的最后一个结点
p1 = SL;//让p1指向链表 的第一个结点
p2 = SL;
while (p1)
{
p2 = p1;
p1 = p1->next;
};
//当跳出while循环的时候,说明 p1已经指向链表的最后一个结点
p2->next = newStudent;
newStudent->next = NULL;
}
return SL;
}
STUDENT* ShanChu(STUDENT* SL, char xm[])
{
STUDENT* p1, * p2;
p1 = SL;
p2 = SL;
//检查是否是首结点
if (strcmp(p1->xm, xm) == 0)
{
p2 = p1->next;
free(p1);
return p2;
}
while (p1)
{
if (strcmp(p1->xm, xm) == 0)//姓名匹配成功,执行删除操作
{
p2->next = p1->next;
free(p1);
break;
}
p2 = p1;
p1 = p1->next;
};
return SL;
}
//对应菜单 添加 的函数
STUDENT* TianJia(STUDENT* SL)
{
STUDENT* pNew;
pNew = (STUDENT*)malloc(sizeof(STUDENT));
int year, month, day;
DATE cs = { 1976,1,15 };
char xm[20], mz[20], bj[20], dz[50], sj[15], ss[50];
char xb[10];
printf("请输入要添加的学生信息:\n");
printf("姓名:");
gets(xm);
strcpy(pNew->xm, xm);
printf("性别:");
gets(xb);
strcpy(pNew->xb, xb);
printf("民族:");
gets(mz);
strcpy(pNew->mz, mz);
printf("出生日期(year-month-day):");
scanf("%d-%d-%d", &year, &month, &day);
pNew->csrq.year = year; pNew->csrq.month = month; pNew->csrq.day = day;
getchar();//吸收所按的回车键
printf("班级:");
gets(bj);
strcpy(pNew->bj, bj);
printf("地址:");
gets(dz);
strcpy(pNew->dz, dz);
printf("手机:");
gets(sj);
strcpy(pNew->sj, sj);
printf("宿舍:");
gets(ss);
strcpy(pNew->ss, ss);
pNew->next = NULL;
SL = tianjiaxuesheng(SL, pNew);
//printf("TianJia-SL:%s\n",SL->bj);
return;
}
void LiuLan(STUDENT* SL)
{
printf("***学生信息浏览***\n");
printf("序号\t姓名\t性别\t民族\t出生日期\t班级\t\t地址\t\t手机\t\t宿舍\n");
STUDENT* p1, * p2;
p1 = SL;
int i = 1;
while (p1)
{
printf("%d\t%s\t%s\t%s\t%d-%d-%d\t%s\t%s\t%s\t%s\n",i++,p1->xm, p1->xb, p1->mz, p1->csrq.year, p1->csrq.month, p1->csrq.day, p1->bj, p1->dz, p1->sj, p1->ss);
p1 = p1->next;
};
return;
}
STUDENT* DaKai(STUDENT* SL)
{
FILE* fp;
STUDENT* p1, * p2;
fp = fopen("student.dat", "rb");
if (fp == NULL)
{
printf("文件打开失败\n");
return;
}
while (1)
{
p1 = (STUDENT*)malloc(sizeof(STUDENT));
fread(p1, sizeof(STUDENT), 1, fp);
if (feof(fp)) break;//如果文件尾,则结束循环
SL = tianjiaxuesheng(SL, p1);
}
fclose(fp);
return SL;
}
//修改指定姓名的学生信息
STUDENT* XiuGai(STUDENT* SL, char xm[])
{
STUDENT* p1, * p2;
p1 = SL;
p2 = SL;
int k;
char xmNew[20], xbNew[10], sjNew[15], bjNew[20], dzNew[50], ssNew[50], mzNew[20];
int newyear, newmonth, newday;
while (p1)
{
if (strcmp(p1->xm, xm) == 0)//姓名匹配成功,执行修改操作
{
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");
scanf("%d", &k);
getchar();
switch (k)
{
case 1:
printf("请输入新的姓名:");
gets(xmNew);
strcpy(p1->xm, xmNew);
break;
case 2:
printf("请输入新的民族:");
gets(mzNew);
strcpy(p1->mz, mzNew);
break;
case 3:
printf("请输入新的性别(M/F):");
gets(xbNew);
strcpy(p1->xb, xbNew);
break;
case 4:printf("出生日期(year-month-day):");
scanf("%d-%d-%d", &newyear, &newmonth, &newday);
p1->csrq.year = newyear; p1->csrq.month = newmonth; p1->csrq.day = newday;
getchar();
break;
case 5:
printf("请输入新的班级:");
gets(bjNew);
strcpy(p1->bj, bjNew);
break;
case 6:printf("请输入新的地址:");
gets(dzNew);
strcpy(p1->dz, dzNew);
break;
case 7:printf("请输入新的手机:");
gets(sjNew);
strcpy(p1->sj, sjNew);
break;
case 8:printf("请输入新的宿舍:");
gets(ssNew);
strcpy(p1->ss, ssNew);
break;
}
}
p2 = p1;
p1 = p1->next;
};
return SL;
}
void BAOCUN(STUDENT* SL)
{
FILE* fp;
STUDENT* p1, * p2;
fp = fopen("student.dat", "wb");
if (fp == NULL)
{
printf("文件打开失败,无法保存学生信息。\n");
return;
}
p1 = SL;//让p1指向链表 的第一个结点
while (p1)
{
p2 = p1;
//将 p2所指向的结点数据,写入文件 fp
fwrite(p2, sizeof(STUDENT), 1, fp);
p1 = p1->next;
};
fclose(fp);
}
void* sort(STUDENT* SL)
{
//插入排序
head = (struct student*)malloc(sizeof(struct student));
head = SL; //把链表第一个结点赋给head
struct student* p = head, * q, * tail;
int i, j, num = 0;
while (p->next)
{
p = p->next;
num++;
}
for (i = 0; i < num - 1; i++)
{
p = head;
q = p->next;
tail = q->next;
num = num - i - 1;
while (num!=0)
{
if (strcmp(tail->sj, q->sj))
{
q->next = tail->next;
tail->next = q;
p->next = tail;
num--;
}
p = p->next;
q = p->next;
tail = q->next;
}
}
printf("链表排序完成!\n");
}
如图,三个文件是学生信息管理系统链表,想问一下,我在使用caozuo.h中的sort排序功能时,只能实现运行一次,排序一次的情况,假如假如40个数据,运行一次,就将第二个结点和第三个结点判断。如何可以运行一次,就把整一个链表排序?