一、项目需求:建立一个简单的学生管理系统,实现增删改查以及二级子菜单。
知识点考察:排序方法方法、结构体、文件的读取等C语言基础知识点。
二、功能模块简要分析
主函数:启动程序主界面显示,菜单循环
int main()
{
DisPlay(); //显示登陆界面
Load(); //加载已经保存的相关学员信息,该信息采取相对路径方式,保存在项目文件夹中
while (Menu())
{
}
return 0;
}
其中Display和Load函数如下:
Display()函数
void DisPlay()//打印界面
{
system("color 3f"); //系统颜色设置 3代表背景色 f代码字体颜色
printf("\n\n");
printf(" \t|--------------------------------------------------------------------------| \n");
printf(" \t|**************************************************************************|\n");
printf(" \t|***--------------------------------------------------------------------***|\n");
printf(" \t|***|******************************************************************|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** 学生管理系统 ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** 作者:我心飞翔 ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** 开发环境:VS2013 ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** 开发日期:2020-06-07 ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|******************************************************************|***|\n");
printf(" \t|***--------------------------------------------------------------------***|\n");
printf(" \t|**************************************************************************|\n");
printf(" \t|--------------------------------------------------------------------------| \n");
printf(" \t|--------------------------按任意键继续------------------------------------| \n");
///system("pause");
char c = getchar();
printf("\n\n");
Load()函数
void Load()
{
FILE* pf = fopen("data.txt", "r");
if (!pf)
return;
int i = 0;
//SUser su;
//while (fread(&su, 1, sizeof(su), pf) > 0)
// g_user[i++] = su;
while (fread(&g_user[i], 1, sizeof(SUser), pf) > 0)
++i;
fclose(pf);
}
启动项目后显示效果如下:
启动该界面后根据实际情况进行选择:按任意键弹出以下窗口
依据条件进行不同设置,包括数据的增删改查及按学号、姓名及分数排序,以及系统背景颜色设置
项目代码如下所示
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//函数声明
void DisPlay();
void Print();
void Add();
void Delete();
void Modify();
void Exit();
void Save();
void Load();
void ColorSet();
int Menu();
struct SUser
{
int nNumb;
char sName[20];
float fMath;
};
SUser g_user[1000];
int CheckNumb(int num)//发现存在返回1
{
int i = 0;
while (g_user[i].nNumb)
{
if (g_user[i].nNumb == num)
return 1;
++i;
}
return 0;
}
void Add()
{
int i =0,nNum;
printf("请输入学号:");
scanf_s("%d", &nNum);
while (CheckNumb(nNum))
{
puts("学号已经存在,请重新输入");
scanf_s("%d", &nNum);
if (nNum == 0)
return;
}
while (g_user[i].nNumb > 0)
++i;//等价于while(g_user[i].sName!=0)
//("%d",&g_user[i].nNumb);
g_user[i].nNumb = nNum;
printf("请输入姓名:");
scanf_s("%s", &g_user[i].sName,sizeof(g_user[i].sName));
printf("请输入数学成绩:");
scanf_s("%f", &g_user[i].fMath);
Save();
Print();
}
void Save()
{
FILE* pf = fopen("data.txt","w");
if (!pf)
{
puts("保存失败");
return ;
}
int i = 0;
while (g_user[i].nNumb)
{
if (-1!=g_user[i].nNumb)
fwrite(&g_user[i], 1, sizeof(SUser), pf);
++i;
}
fclose(pf);
}
void Load()
{
FILE* pf = fopen("data.txt", "r");
if (!pf)
return;
int i = 0;
//SUser su;
//while (fread(&su, 1, sizeof(su), pf) > 0)
// g_user[i++] = su;
while (fread(&g_user[i], 1, sizeof(SUser), pf) > 0)
++i;
fclose(pf);
}
void Print() //打印相关信息函数
{
puts("\n\t\t学号\t姓 名\t数学");
int i = 0,sum=0;
while (g_user[i].nNumb) //学号不能为零
{
if (g_user[i].nNumb>0)
{
printf("\t\t%d\t%s\t%0.1f\n", g_user[i].nNumb, g_user[i].sName, g_user[i].fMath);
++sum; //记录学员个数
}
++i;
}
printf("\t\t总共有%d个学生信息\n\n",sum);
Save();
system("pause"); //等待屏幕输入
}
void Delete()
{
printf("请输入要删除的学号:");
int nNum;
scanf_s("%d",&nNum);
int i = 0;
while (g_user[i].nNumb)
{
if (g_user[i].nNumb==nNum)
{
g_user[i].nNumb = -1;
break;
}
++i;
}
if (!g_user[i].nNumb)
{
puts("你输入的学号不存在");
return;
}
puts("删除成功!");
Save();
}
void Modify()
{
printf("\t\t请输入要更改的学号");
int numb;
scanf_s("%d",&numb);
int i = 0;
while (g_user[i].nNumb)
{
if (g_user[i].nNumb == numb) //输入学号等于系统保存的学号,则可以修改,否则提示未找到输入的学号
break;
++i;
}
if (!g_user[i].nNumb)
{
puts("\t\t您输入的学号不存在");
return;
}
printf("\t\t%d\t%s\t%0.1f\n",g_user[i].nNumb,g_user[i].sName,g_user[i].fMath);
printf("\t\t请输入要修改的姓名:");
scanf_s("%s", g_user[i].sName, sizeof(g_user[i].sName));
printf("\t\t请输入要修改数学成绩:");
scanf_s("%f", g_user[i].fMath);
Save();
Print();
}
void Find()
{
printf("\t\t请输入要查找的学号");
int numb;
scanf_s("%d", &numb);
int i = 0;
while (g_user[i].nNumb)
{
if ((g_user[i].nNumb != numb)||(!g_user[i].nNumb))
{
return;
}
else
printf("\t\t%d\t%s\t%0.1f\n", g_user[i].nNumb, g_user[i].sName, g_user[i].fMath);
++i;
}
}
void Sort(int index)//冒泡排序法
{
int i = 0, n = 0;
while (g_user[n].nNumb)
++n; //遍历计算出有多少个学号
while (i<n - 1)
{
int j = 0;
while (j<n - i - 1)
{
if (Judge(index,j))
{
SUser st = g_user[j];
g_user[j] = g_user[j + 1];
g_user[j + 1] = st;
}
++j;
}
++i;
}
}
void DisPlay()//打印界面
{
system("color 3f"); //系统颜色设置 3代表背景色 f代码字体颜色
printf("\n\n");
printf(" \t|--------------------------------------------------------------------------| \n");
printf(" \t|**************************************************************************|\n");
printf(" \t|***--------------------------------------------------------------------***|\n");
printf(" \t|***|******************************************************************|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** 学生管理系统 ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** 作者:我心飞翔 ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** 开发环境:VS2013 ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** 开发日期:2020-06-07 ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|******************************************************************|***|\n");
printf(" \t|***--------------------------------------------------------------------***|\n");
printf(" \t|**************************************************************************|\n");
printf(" \t|--------------------------------------------------------------------------| \n");
printf(" \t|--------------------------按任意键继续------------------------------------| \n");
///system("pause");
char c = getchar();
printf("\n\n");
}
//void SortByNumb()
//{
// int i = 0, n = 0;
// while (g_user[n].nNumb)
// ++n;
// while (i<n-1)
// {
// int j = 0;
// while (j<n-i-1)
// {
// if (g_user[j].nNumb>g_user[j+1].nNumb)
// {
// SUser st = g_user[j];
// g_user[j] = g_user[j + 1];
// g_user[j + 1] = st;
// }
// ++j;
// }
// ++i;
// }
//}
//
//void SortByName()
//{
// int i = 0, n = 0;
// while (g_user[n].nNumb)
// ++n;
// while (i<n - 1)
// {
// int j = 0;
// while (j<n - i - 1)
// {
// if (strcmp(g_user[j].sName,g_user[j+1].sName)>0)
// {
// SUser st = g_user[j];
// g_user[j] = g_user[j + 1];
// g_user[j + 1] = st;
// }
// ++j;
// }
// ++i;
// }
//}
//
//void SortByScore()
//{
// int i = 0, n = 0;
// while (g_user[n].nNumb)
// ++n;
// while (i<n-1)
// {
// int j = 0;
// while (j<n-i-1)
// {
// if (g_user[j].fMath<g_user[j+1].fMath)
// {
// SUser st = g_user[j];
// g_user[j] = g_user[j + 1];
// g_user[j + 1] = st;
// }
// ++j;
// }
// ++i;
// }
//}
int DispMenu() //二级子菜单,分别是先按照学号/姓名/分数进行排序
{
system("cls");
puts("\t\t1.按学号排序");
puts("\t\t2.按姓名排序");
puts("\t\t3.按成绩排序");
puts("\t\t0.返回主菜单");
printf("\t\t请选择:");
int i = 0;
scanf_s("%d", &i);
switch (i)
{
case 1:
case 2:
case 3:
Sort(i);
Print();
}
return i;
}
void ColorSet() //系统桌面背景设置函数
{
/*
COLOR [attr]
attr 指定控制台输出的颜色属性。颜色属性由两个十六进制数字指定 -- 第一个
对应于背景,第二个对应于前景。每个数字可以为以下任何值:
0 = 黑色 8 = 灰色
1 = 蓝色 9 = 淡蓝色
2 = 绿色 A = 淡绿色
3 = 浅绿色 B = 淡浅绿色
4 = 红色 C = 淡红色
5 = 紫色 D = 淡紫色
6 = 黄色 E = 淡黄色
7 = 白色 F = 亮白色
*/
puts("\t\t0 = 黑色 1 = 蓝色");
puts("\t\t2 = 绿色 3 = 浅绿色");
puts("\t\t4 = 红色 5 = 紫色");
puts("\t\t6 = 黄色 7 = 白色");
puts("\t\t8 = 灰色 9 = 淡蓝色");
puts("\t\tA = 淡绿色 B = 淡浅绿色");
puts("\t\tC = 淡红色 D = 淡紫色");
puts("\t\tE = 淡黄色 F = 亮白色");
printf("\t\t请选择背景颜色:[0-F]");
char s[10] = "color ";//目的是使用system("color 3f");函数,思路:一个字符串+输入两个十六进颜色选项
fflush(stdin);
s[6] = getchar();
printf("\t\t请输入前景色【0-F】:");
fflush(stdin);
s[7] = getchar();
//方法二,使用system("color 3f")函数
//int x, y;
//printf("\t\t请输入背景色:【0-F】");
//scanf_s("%x",&x);
//printf("\t\t请输入前景色:【0-F】");
//scanf_s("%x", &y);
//char s[10];
//sprintf(s,"color %x%x",x,y);
//system(s); //调用字符串,实现system("color 3f")形式函数
}
int Menu()
{
system("cls");
puts("\t\t1.浏览所有信息");
puts("\t\t2.增加信息");
puts("\t\t3.删除信息");
puts("\t\t4.修改信息");
puts("\t\t5.查找信息");
puts("\t\t6.颜色设置");
puts("\t\t0.退出");
int i = 0;
printf("\t\t请选择:");
scanf_s("%d",&i);
switch (i)
{
case 1:
while(DispMenu());
//Print();
break;
case 2:
Add();
break;
case 3:
Delete();
break;
case 4:
Modify();
break;
case 5:
Find();
break;
case 6:
ColorSet();
break;
case 0:
Exit();
}
return i;
}
int main()
{
DisPlay(); //显示登陆界面
Load(); //加载已经保存的相关学员信息,该信息采取相对路径方式,保存在项目文件夹中
while (Menu())
{
}
return 0;
}
采用链表方式实现增删改查
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<string.h>
void Display();
void Add();
void Find();
void Delete();
void Input(int index);
void Exit();
void Save();
void Load();
void ColorSet();
int Menu();
int DispMenu();
struct SUser
{
int nNumb;
char sName[20];
float fMath;
};
typedef struct SUser DATA;
struct sNode
{
DATA data;
sNode* pNext;
};
sNode*g_pHead = NULL;//头指针
//链表的插入--头插入
void AddHead(DATA data)//头插法:每次插入都从头插入
{
sNode* p = (sNode*)malloc(sizeof(sNode));
p->data = data;
p->pNext = g_pHead;
g_pHead = p;
}
//链表的插入--尾插入
void AddTail(DATA data)
{
sNode* pNew = (sNode*)malloc(sizeof(sNode));
pNew->data = data;
pNew->pNext = NULL;
if (!g_pHead)
{
g_pHead = pNew;
return;
}
sNode* p = g_pHead;
while (p->pNext != NULL)
p = p->pNext;
p->pNext = pNew;
}
void Printt()
{
puts("学号\t姓名\t成绩");
sNode*p = g_pHead;
int i = 0;
while (p != NULL)
{
printf("%d\t%s\t%f\n", p->data.nNumb,p->data.sName,p->data.fMath);
p = p->pNext;
++i;
}
printf("总共有%d条学生信息",i);
system("pause");
}
int AddMenu()
{
system("cls");
puts("\n\n\t\t1.向头部插入");
puts("\t\t2.向尾部插入");
puts("\t\t0.回到主菜单");
int i = 0;
scanf_s("%d",&i);
switch (i)
{
case 1:
case 2:
Input(i);
break;
}
return i;
}
void Input(int index)
{
int numb;
printf("请输入学号:");
scanf_s("%d", &numb);
DATA data;
data.nNumb = numb;
printf("请输入姓名:");
scanf_s("%s", &data.sName, sizeof(data.sName));
printf("请输入成绩:");
scanf_s("%f", &data.fMath);
if (index==1)
AddHead(data);
else
AddTail(data);
Save();
Printt();
}
void Load()
{
FILE*pf = fopen("student.txt", "r");
if (!pf)
return;
DATA data;
while (fread(&data ,1, sizeof(data),pf )== sizeof(data))
AddTail(data);
fclose(pf);
}
void Save()
{
FILE*pf = fopen("student.txt","w");
if (!pf)
return;
sNode* p = g_pHead;
while (p)
{
fwrite(&p->data,1,sizeof(p->data),pf);
p = p->pNext;
}
fclose(pf);
}
void Modify()
{
int numb;
printf("请输入要修改的学号:");
scanf_s("%d",&numb);
sNode* p = g_pHead;
while (p->pNext)
{
if (p->data.nNumb == numb)
break;
p = p->pNext;
}
if (!p)
{
puts("输入的不存在");
return;
}
printf("%d\t%s\t%f\n\n",p->data.nNumb, p->data.sName, p->data.fMath);
printf("请输入姓名和成绩:");
scanf_s("%s%f",p->data.sName,sizeof(p->data.sName),&(p->data.fMath));
Save();
Printt();
}
void Find()
{
int numb;
printf("请输入要查找的学号:");
scanf_s("%d", &numb);
sNode* p = g_pHead;
while (p->pNext)
{
if (p->data.nNumb != numb | !p->data.nNumb)
return;
else
{
printf("%d%s%f", p->data.nNumb, p->data.sName, p->data.fMath);
}
p = p->pNext;
}
if (!p)
{
puts("不存在");
return;
}
}
int DelNumb(int numb)
{
sNode* p = g_pHead, *p1 = NULL;
if (!p)
return 0;
if (p->data.nNumb == numb)
{
g_pHead = p->pNext;
free(p);
return 1;
}
while (p->pNext)
{
if (p->data.nNumb == numb)
{
p1->pNext = p->pNext;
free(p);
return 1;
}
p1 = p;
p = p->pNext;
}
return 0;
}
void Delete()
{
char c;
do
{
int numb;
printf("请输入要删除的学号:");
scanf_s("%d", &numb);
if (DelNumb(numb))
{
Save();
Printt();
}
else
{
puts("删除失败!");
}
printf("是否要继续删除?(y/n)");
c = getchar();
} while (c=='y'|c=='Y');
}
void Exit()
{
}
void ColorSet()
{
/*
COLOR [attr]
attr 指定控制台输出的颜色属性。颜色属性由两个十六进制数字指定 -- 第一个
对应于背景,第二个对应于前景。每个数字可以为以下任何值:
0 = 黑色 8 = 灰色
1 = 蓝色 9 = 淡蓝色
2 = 绿色 A = 淡绿色
3 = 浅绿色 B = 淡浅绿色
4 = 红色 C = 淡红色
5 = 紫色 D = 淡紫色
6 = 黄色 E = 淡黄色
7 = 白色 F = 亮白色
*/
puts("\t\t0 = 黑色 1 = 蓝色");
puts("\t\t2 = 绿色 3 = 浅绿色");
puts("\t\t4 = 红色 5 = 紫色");
puts("\t\t6 = 黄色 7 = 白色");
puts("\t\t8 = 灰色 9 = 淡蓝色");
puts("\t\tA = 淡绿色 B = 淡浅绿色");
puts("\t\tC = 淡红色 D = 淡紫色");
puts("\t\tE = 淡黄色 F = 亮白色");
printf("\t\t请选择背景颜色:[0-F]");
char s[10] = "color "; //目的是使用system("color 3f");函数,思路:一个字符串+输入两个十六进颜色选项
fflush(stdin);
s[6] = getchar();
printf("\t\t请输入前景色【0-F】:");
fflush(stdin);
s[7] = getchar();
//方法二,使用system("color 3f")函数
//int x, y;
//printf("\t\t请输入背景色:【0-F】");
//scanf_s("%x",&x);
//printf("\t\t请输入前景色:【0-F】");
//scanf_s("%x", &y);
//char s[10];
//sprintf(s,"color %x%x",x,y);
//system(s); //调用字符串,实现system("color 3f")形式函数
}
void DisPlay()//打印界面
{
system("color 3f"); //系统颜色设置 3代表背景色 f代码字体颜色
printf("\n\n");
printf(" \t|--------------------------------------------------------------------------| \n");
printf(" \t|**************************************************************************|\n");
printf(" \t|***--------------------------------------------------------------------***|\n");
printf(" \t|***|******************************************************************|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** 学生管理系统 ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** 作者:我心飞翔 ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** 开发环境:VS2013 ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** 开发日期:2020-06-07 ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|*** ***|***|\n");
printf(" \t|***|******************************************************************|***|\n");
printf(" \t|***--------------------------------------------------------------------***|\n");
printf(" \t|**************************************************************************|\n");
printf(" \t|--------------------------------------------------------------------------| \n");
printf(" \t|--------------------------按任意键继续------------------------------------| \n");
///system("pause");
char c = getchar();
Load();
printf("\n\n");
}
int Menu()
{
system("cls");
puts("\t\t1.浏览所有信息");
puts("\t\t2.增加信息");
puts("\t\t3.删除信息");
puts("\t\t4.修改信息");
puts("\t\t5.查找信息");
puts("\t\t6.颜色设置");
puts("\t\t0.退出");
int i = 0;
printf("\t\t请选择:");
scanf_s("%d", &i);
switch (i)
{
case 1:
while (DispMenu());
break;
case 2:
while(AddMenu());
break;
case 3:
Delete();
break;
case 4:
Modify();
break;
case 5:
Find();
break;
case 6:
ColorSet();
break;
case 0:
Exit();
}
return i;
}
int Jude(sNode*q, sNode* m, int index)
{
switch (index)
{
case 1:
return q->data.nNumb < m->data.nNumb;
break;
case 2:
return strcmp(q->data.sName,m->data.sName)<0;
break;
case 3:
return q->data.fMath < m->data.fMath;
break;
}
return 0;
}
void Sort(int index)
{
sNode*p = g_pHead;
if (!p)
return;
while (p->pNext)
{
sNode*q = p->pNext;
sNode* m = p;
while (q)
{
if (Jude(q,m,index))
m = q;
q = q->pNext;
}
if (m!=p)
{
DATA t = p->data;
p->data = m->data;
m->data = t;
}
p = p->pNext;
}
}
int DispMenu() //二级子菜单,分别是先按照学号/姓名/分数进行排序
{
system("cls");
puts("\t\t1.按学号排序");
puts("\t\t2.按姓名排序");
puts("\t\t3.按成绩排序");
puts("\t\t0.返回主菜单");
printf("\t\t请选择:");
int i = 0;
scanf_s("%d", &i);
switch (i)
{
case 1:
case 2:
case 3:
Sort(i);
//Printt();
break;
}
Printt();
return i;
}
int main()
{
DisPlay();
while (Menu())
{
}
return 0;
}