一、功能介绍:
该系统包括录入学生信息、打印学生信息、保存学生信息、读取学生信息、统计学生人数、查找学生信息、修改学生信息、删除学生信息和退出。
1.先设计一个DisPlay函数进行该系统整体页面的展示,直接用printf函数打印出页面,比较简单。
void DisPlay()//起始界面函数
{
printf("*********************************\n");
printf("*\t学生成绩管理系统\t*\n");
printf("*********************************\n");
printf("*\t请选择功能列表 \t*\n");
printf("*********************************\n");
printf("*\t1.录入学生信息 \t*\n");
printf("*\t2.打印学生信息 \t*\n");
printf("*\t3.保存学生信息 \t*\n");
printf("*\t4.读取学生信息 \t*\n");
printf("*\t5.统计学生人数 \t*\n");
printf("*\t6.查找学生信息 \t*\n");
printf("*\t7.修改学生信息 \t*\n");
printf("*\t8.删除学生信息 \t*\n");
printf("*\t9.退出 \t*\n");
printf("*********************************\n");
}
2.录入学生姓名:
该部分的设计需要用到单链表。首先先创建出一个新节点进行学生信息的保存,然后用头插法进行前一个链表和后一个链表的链接。用scanf函数从键盘接收学生的信息。
void InputStudent()//录入学生姓名
{
//创建一个新节点
Node* pNewNode =(Node*)malloc(sizeof(Node));
pNewNode->pNext = NULL;
//头插法
if (g_pHead == NULL)
{
g_pHead = pNewNode;
}
else
{
pNewNode->pNext = g_pHead;
g_pHead = pNewNode;
}
printf("请输入学生姓名:\n");
scanf("%s",pNewNode->stu.name);//接收一个字符串
printf("请输入学生年龄:\n");
scanf("%d",&pNewNode->stu.age);
printf("请输入学生学号:\n");
scanf("%d",&pNewNode->stu.stunum);
printf("请输入学生成绩:\n");
scanf("%d",&pNewNode->stu.score);
printf("信息录取成功!\n");
system("pause");//暂停
system("cls");//清屏
}
3.打印学生信息:
同样,直接用printf函数打印出提示界面,然后遍历整个链表即可打印学生信息。
void PrintStudent()//打印学生信息
{
system("cls");
printf("*********************************\n");
printf("*\t学生成绩管理系统\t*\n");
printf("*********************************\n");
printf("学号 姓名 年龄 成绩\n");
printf("*********************************\n");
//遍历链表
Node* p = g_pHead;
while (p != NULL)
{
printf("%d %s %d %d\n",p->stu.stunum,p->stu.name,p->stu.age,p->stu.score);
p = p->pNext;
}
printf("*********************************\n");
system("pause");
system("cls");
}
4.保存学生信息:
需要用到文件系统的相关知识。首先打开文件(fopen函数),用一个指针去接收。我这里用了一个if判断是否为空,若为空则提示文件打开失败。之后遍历链表就能完成文件的写入。最后还要用fclose函数来关闭文件,然后提示“数据保存成功”。最后暂停并清屏。
void SaveStudent()//保存学生信息
{
//打开文件
FILE* fp= fopen("E:\\stuinfo.txt","w");
if (fp==NULL)
{
printf("文件打开失败\n");
return;
}
//遍历链表
Node* p = g_pHead;//定义一个节点指针让其指向头,从头开始遍历
while (p != NULL)
{
fwrite(&p->stu,1,sizeof(Student),fp);
p = p->pNext;
}
//关闭文件
fclose(fp);
printf("\n数据保存成功\n");
system("pause");
system("cls");
}
5.读取学生信息:
还是一样,先打开文件,同上。然后用while循环进行遍历。也是要创建一个新节点并用头插法对数据进行连接。最后别忘了关闭文件。(可以读取系统文件中所保存的学生信息)
void ReadStudent()//读取学生信息
{
//打开文件
FILE *fp=fopen("E:\\stuinfo.txt","r");
if (fp==NULL)
{
printf("打开文件失败\n");
return;
}
//读取文件
Student stu;
while (fread(&stu, 1, sizeof(Student), fp))
{
//创建一个新节点
Node* pNewNode=(Node*)malloc(sizeof(Node));
pNewNode->pNext = NULL;
memcpy(pNewNode,&stu,sizeof(Student));
//头插法
if (g_pHead == NULL)
{
g_pHead = pNewNode;
}
else
{
pNewNode->pNext = g_pHead;
g_pHead = pNewNode;
}
}
//关闭文件
fclose(fp);
printf("加载数据成功!\n");
system("pause");
system("cls");
}
6.统计学生人数:
函数的返回值是一个整数类型。
int CountStudent()//统计学生人数
{
int nCount = 0;//学生总数
//遍历
Node* p = g_pHead;
while (p!=NULL)
{
nCount++;
p = p->pNext;
}
return nCount;
}
7.查找学生信息:用int和char型分别接收输入的学号和姓名。
还是先创建一个头节点,用while当不为空指针时,进行循环;再用一个if判断从键盘输入的学号或姓名是否和系统已经保存的信息一致。注意:这里判断姓名时,我们用了一个strcmp函数进行比较,strcmp是字符串比较函数。当两个字符串相等时则为0。if判断为真则返回了p指针,然后接着指向下一个节点。
Node* FindStudent()//查找学生信息
{
int nStuNum;
char szName[20];
printf("请输入要查找学生的学号:\n");
scanf("%d",&nStuNum);
printf("请输入要查找的学生的姓名:\n");
scanf("%s",szName);
Node* p = g_pHead;
while (p!=NULL)
{
if (p->stu.stunum==nStuNum || 0==strcmp(p->stu.name,szName))//用字符串比较函数(strcmp)判断所输入的名字
{
return p;
}
p = p->pNext;
}
return NULL;
}
8.修改学生信息:
还是和之前一样,创建一个头节点,用while当不为空时进行判断,注意:在键盘获取时,如果为字符型不用取地址,如果为整型别忘了取地址!!!然后当修改成功时break跳出循环。然后继续指向下一节点。用了一个if判断若为空即表示从键盘输入的学生信息有误。最后暂停、清屏。
void ModifyStudent()//修改学生信息
{
int nStuNum;
printf("请输入需要修改的学生学号:\n");
scanf("%d",&nStuNum);
Node* p = g_pHead;
while (p != NULL)
{
if (p->stu.stunum==nStuNum)//判断所要修改的学生学号
{
printf("请输入要修改的学生姓名 年龄 成绩:\n");
scanf("%s %d %d",p->stu.name,&p->stu.age,&p->stu.score);
printf("修改成功!\n");
break;
}
p = p->pNext;
}
if (p==NULL)
{
printf("未找到该学生信息!\n");
}
system("pause");
system("cls");
}
9.删除学生信息:
首先定义一个学号nStuNum,然后从键盘获取要删除的学生信息。
先判断是否为头节点,若为头节点就不需要去连接。因为要把头节点删掉(也就是释放内存),那么新的头节点需要备份一个,所以定义一个p1,然后用p1去备份。之后进行释放。
void DeleteStudent()//删除学生信息
{
int nStuNum;
printf("请输入要删除的学生学号:\n");
scanf("%d", &nStuNum);
Node* p1, * p2;
if (g_pHead->stu.stunum == nStuNum)//判断是否为头节点
{
p1 = g_pHead;//备份
g_pHead = g_pHead->pNext;
free(p1);
system("pause");
system("cls");
return;
}
//若不是头节点
Node* p = g_pHead;
while (p->pNext != NULL)
{
if (p->pNext->stu.stunum == nStuNum)
{
p2 = p->pNext;//备份
p->pNext = p->pNext->pNext;
free(p2);
return;
}
p = p->pNext;
if (p->pNext == NULL)
{
break;
}
}
if (p->pNext = NULL)
{
printf("未找到该学生\n");
}
system("pause");
system("cls");
}
10.退出系统
case'9':printf("退出系统成功!\n"); return 0; default:printf("输入有误,请重新输入!\n");
system("pause");
system("cls");
break;//退出