第一个先定好思路模板例如:
有两大模板,第一个管理员,第二个学生用户,在这里申明一下,学生的功能其实与管理员差不了多少,举个例子,管理员有五六个功能,而且用的是开关语句。那么学生选择是一样的,只有一两个,直接拷贝过来,删掉几个开关就好了来看看功能:
以上是管理员的,再来看看学生的
其实代码都差不多。
说到学生管理系统最主要的功能还是增删查改,还有链表涉及以及应用,
增加学生以及数据:
我这里用的是单项列表的头插法,然后保存数据,
小编在此强调到最后一定要关闭文件,,这个错误,小编找了半个小时,很多人都会忽略。
删除学生信息,可以根据学生的学号以及姓名来查找然后来指定删除。
删除后还要进行保存;
修改与查询都一样的根据学号与姓名来查找,然后进行操作。
排序,我这里没用数据结构的排序算法,我这里是用的比较大小进行排序,来看关键代码
这些就是管理员的功能操作,
然后来看看学生的功能操作,
学生的功能只有两个,一个是查询,二个就是修改个人信息,
查询就是根据自己学号来查找,修改也是根据学号与姓名来查找与学号来找并且进行修改然后保存数据。
功能与管理员功一样,修改一下就可以用在学生用户的功能上,在这里就不啰嗦了。
另外,我这里用的是多文件编译
先来看看.h文件
#ifndef _HIDE_H__
#define _HIDE_H__
#include "mystdio.h"
#include<stdlib.h>
#include<string.h>
#include <termios.h>
#include <unistd.h>
int getch(void);
void GetString(char *buf);
void hidepassword();
typedef struct Node
{
int ID;// 学号
char Name[50];// 姓名
char Sex[10];// 性别
char Class[50];// 班级
char Room[20];// 宿舍号
int Score;// 成绩
struct Node* next;// 指针域
}node;
// 读取文件
int Read_FILE(node* L);
// 保存文件
int Save_FILE(node* L);
// 主菜单界面
void welcome();
// 增加学生信息
void Add(node *L,node e);// 功能
void Add_Printf();// 界面
// 删除学生信息
void Delete_Printf(node*L);// 界面
void Delete(node* s);// 功能
// 修改学生信息
void Fix(node *L);
// 查询学生信息
void Search_Printf(node* L);// 界面
node* Search_id(int id, node* L);// 按学号进行查找
node* Search_name(char name[], node* L);// 按姓名进行查找
// 输出学生信息
void Print(node* L);// 功能
void Print_Printf();// 界面
// 排序学生信息
void Sort(node* L);
bool cmp_big_ID(node e1, node e2);// 学号从大到小
bool cmp_big_Score(node e1, node e2);// 成绩从大到小
bool cmp_small_ID(node e1, node e2);// 学号从小到大
bool cmp_small_Score(node e1, node e2);// 成绩从小到大
// 退出管理系统
void goodbye();
void M_Clear(node* L);
void mima();
void xueshen();
void modifyxs();
void grcx();
void Fix1(node* L);
#endif
.c文件
/************************************************************************************************************************************************************************************************************************
*描 述: 此为最新版本
*作者名: 齐天大圣
*文件名: 111.c
*时 间: 2022-12-13 20:56
*作 用: 迎风一刀斩
****************************************************************************************************************************************************************************************************************************/
#include "mystdio.h"
#include "111.h"
int getch(void)
{
struct termios tm, tm_old;
int fd = STDIN_FILENO, c;
if (tcgetattr(fd, &tm) < 0)
return -1;
tm_old = tm;
#if 0
cfmakeraw(&tm);
#else
tm.c_lflag &= ~(ECHO | ECHONL | ICANON);
#endif
if (tcsetattr(fd, TCSANOW, &tm) < 0)
return -1;
c = fgetc(stdin);
if (tcsetattr(fd, TCSANOW, &tm_old) < 0)
return -1;
return c;
}
void GetString(char *buf)//这是密码加密功能函数
{
int i;
char ch;
i = 0;
while (1)
{
ch = getch();
if (ch == '\n')
{
break;
}
else if (ch == 127)
{
if (i > 0)
{
printf("\b \b");
buf[--i] = '\0';
}
i--;
}
else
{
buf[i] = ch;
printf("*");
}
i++;
}
buf[++i] = '\0';
printf("\n");
}
void hidepassword()//这是更改密码函数
{
char password1[256] = {0};
char password2[256] = {0};
printf("Password:");
GetString(password1);
printf("Verify:");
GetString(password2);
if (strncmp(password1, password2, 256) == 0)
{
printf("Set Password Ok!\nPassword:%s\n", password1);
}
else
{
printf("Verify Error!\n%s is not equal %s\n", password1, password2);
}
}
extern node list; // 链表
void mima()//总界面
{
printf("--------------------------------------------------------------------------------------------------------------------------------------------------------\n");
printf("\033[35m\n");
printf("\033[33m\n");
printf("\033[33m\n");
printf("\033[33m\n");
printf("\033[33m\033[36m 欢迎来到学生管理系统\n");
printf("\033[33m\n");
printf("\033[33m\n");
printf("\033[33m\n");
printf("\033[33m\033[31m 1,管理员 2,学生用户\n");
printf("\033[33m\n");
printf("\033[39m\n");
printf("\n");
printf("========================================================================================================================================================\n");
}
void welcome()//管理员功能界面
{
system("cls");
printf("\033[33m\033[36m\n");
printf("\033[33m\033[36m 1,增加学生\n");
printf("\n");
printf("\033[33m\033[36m 2,删除学生\n");
printf("\n");
printf("\033[33m\033[36m 3,修改学生信息\n");
printf("\n");
printf("\033[33m\033[36m 4,查寻学生\n");
printf("\n");
printf("\033[33m\033[36m 5,显示全部学生\n");
printf("\n");
printf("\033[33m\033[36m 6,学生信息排序\n");
printf("\n");
printf("\033[33m\033[36m 7,返回界面\n");
printf("\n");
printf("\033[33m\033[36m 8,更改密码\n");
printf("\n");
printf("\033[33m\033[36m 9,清空学生信息\n");
printf("\033[33m\033[37m 请选择想要实现的功能(数字):");
}
// 读取文件,
/*这是读取文件,我打开这个.txt文件。判断这个是否为空。是空就返回,不为空,重新申请一个内存空间
,直接赋值给新空间,然后用头插法进行操作,这个地方我用的是单项列表,然后关闭文件*/
/*我们可以将之前已经在文件中写的一部分信息,保存在文件中,当我们要读取它们的时候,
从文件中读取它们,并将它们放入链表中,不用担心每次打开信息就会丢失的问题。
这里就需要用到文件的读取以及链表的插入相关的知识点。
这里文件的读取,我选择的是 fscanf()函数,而链表的插入我选择的是头插法。*/
int Read_FILE(node* L)
{
FILE* pfRead = fopen("student_information.txt", "r");
node st;
node* s;
node* t = L;
if (pfRead == NULL)
{
return 0;
}
while (fscanf(pfRead, " %d %s %s %s %s %d", &st.ID, st.Name, st.Sex, st.Class, st.Room, &st.Score) != EOF)
{
s = (node*)malloc(sizeof(node));
*s = st;
// 头插法
s->next=t->next;
t->next=s;
}
fclose(pfRead);
return 0;
}
// 保存文件
/*我们用之前的.txt文件保存所写下来的数据信息,使用的时候用读的方式打开*/
int Save_FILE(node* L)
{
FILE* pfWrite = fopen("student_information.txt", "r");
if (pfWrite == NULL)
{
return 0;
}
node* p = L->next;
while (p != NULL)//这里,我用while循环保存,简单来说,来一个数据,我就保存
{
fprintf(pfWrite, " %d %s %s %s %s %d\n", p->ID, p->Name, p->Sex, p->Class, p->Room, p->Score);
p = p->next;
}
fclose(pfWrite);//关闭文件
return 1;
}
// 增加学生信息
void Add_Printf()
{
system("cls");
node st;
printf("\033[33m\033[39m请输入新增学生的相关信息:\n");
printf("学号:");
scanf("%d", &st.ID);
printf("姓名:");
scanf("%s", st.Name);
printf("性别:");
scanf("%s", st.Sex);
printf("班级:");
scanf("%s", st.Class);
printf("宿舍号:");
scanf("%s", st.Room);
printf("成绩:");
scanf("%d", &st.Score);
Add(&list, st);
}
void Add(node* L, node e)//增加学生信息,用链表保存下来
{
// 头插法
node* p = L;
node* s = (node*)malloc(sizeof(node));
*s = e;
s->next = p->next;
p->next = s;
Save_FILE(L);
}
// 删除学生信息
void Delete_Printf(node* L)
{
system("cls");
int id;
node* p;//结构体指针
printf("\033[33m\033[39m请输入要删除的学生的学号:");
scanf("%d", &id);
node* st = Search_id(id, L);//这是调用了依据学号来查找的函数(指针)
p = st;
if (st == NULL)
{
printf("查无此人!\n");
return;
}
st = st->next;
printf("\033[33m\033[36m________________________________________________________________\n");
printf("|学号\t|姓名\t|性别\t|班级\t\t|宿舍号\t\t|成绩\t|\n");
printf("________________________________________________________________\n");
printf("|%d\t |%s\t |%s\t |%s\t |%s\t |%d\t |\n", st->ID, st->Name, st->Sex, st->Class, st->Room, st->Score);
printf("________________________________________________________________\n");
Delete(p);//删除指针指向的功能
// 保存信息
Save_FILE(L);
}
void Delete(node* s)//单项列表进行删除
{
node* t = s->next;
s->next = t->next;
t->next = NULL;
free(t);//释放
}
// 修改学生信息
void Fix(node* L)
{
system("cls");
int id;
printf("\033[33m\033[33m请输入要修改的学生的学号:");
scanf("%d", &id);
node* st = Search_id(id, L);//按照学号来寻找需要修改的学生信息
if (st == NULL)
{
printf("查无此人!\n");
return;
}
st = st->next;//寻找下一个
int choice = 0;//自定义变量
while (1)
{
system("cls");
// 输出一次所要修改的学生成绩
printf("\033[33m\033[36m________________________________________________________________\n");
printf("|学号\t|姓名\t|性别\t|班级\t\t|宿舍号\t\t|成绩\t|\n");
printf("________________________________________________________________\n");
printf("|%d\t |%s\t |%s\t |%s\t |%s\t |%d\t |\n", st->ID, st->Name, st->Sex, st->Class, st->Room, st->Score);
printf("________________________________________________________________\n");
printf("修改姓名 ---- 1\n");
printf("修改性别 ---- 2\n");
printf("修改班级 ---- 3\n");
printf("修改宿舍号 ---- 4\n");
printf("修改成绩 ---- 5\n");
printf("\033[33m\033[335m请输入要修改的信息:");
scanf("%d", &choice);
switch (choice)
{
case 1:
printf("请输入姓名:");
scanf("%s", st->Name);//这是结构体里面所有的参数
break;
case 2:
printf("请输入性别:");
scanf("%s", st->Sex);
break;
case 3:
printf("请输入班级:");
scanf("%s", st->Class);
break;
case 4:
printf("请输入宿舍号:");
scanf("%s", st->Room);
break;
case 5:
printf("请输入成绩:");
scanf("%d",&st->Score);
break;
}
printf("是否继续修改该学生信息?(Yes:1 / No:0):");
scanf("%d", &choice);
if (choice == 0)
{
break;
}
}
// 修改完成后该学生的信息
printf("\033[33m\033[36m________________________________________________________________\n");
printf("|学号\t|姓名\t|性别\t|班级\t\t|宿舍号\t\t|成绩\t|\n");
printf("________________________________________________________________\n");
printf("|%d\t |%s\t |%s\t |%s\t |%s\t |%d\t |\n", st->ID, st->Name, st->Sex, st->Class, st->Room, st->Score);
printf("________________________________________________________________\n");
// 保存信息
Save_FILE(L);
}
// 查询学生信息
void Search_Printf(node* L)
{
system("cls");
int choice = 0;//查询有两种方式
printf("\033[33m\033[31m按照学号查询 ---- 1\n");
printf("按照姓名查询 ---- 2\n");
printf("请输入查询方式:");
scanf("%d", &choice);
int id;
char name[50];
node* st;
if (choice == 1)//用判断来是否对应所输入的数值,
{
printf("请输入要查询的学号:");
scanf("%d", &id);
st = Search_id(id, L);
if (st == NULL)
{
printf("查无此人!\n");
}
else
{
st = st->next;
printf("\033[33m\033[36m________________________________________________________________\n");
printf("|学号\t|姓名\t|性别\t|班级\t\t|宿舍号\t\t|成绩\t|\n");
printf("________________________________________________________________\n");
printf("%d|%s\t|%s\t|%s\t|%s\t|%d\t|\n", st->ID, st->Name, st->Sex, st->Class, st->Room, st->Score);
printf("________________________________________________________________\n");
}
}
else if (choice == 2)
{
printf("请输入要查询的姓名:");
scanf("%s", name);
st = Search_name(name, L);
if (st == NULL)
{
printf("查无此人!\n");
}
else
{
st = st->next;
printf("\033[33m\033[36m________________________________________________________________\n");
printf("|学号\t|姓名\t|性别\t|班级\t\t|宿舍号\t\t|成绩\t|\n");
printf("________________________________________________________________\n");
printf("|%d\t |%s\t |%s\t |%s\t |%s\t |%d\t |\n", st->ID, st->Name, st->Sex, st->Class, st->Room, st->Score);
printf("________________________________________________________________\n");
}
}
}
// 按学号进行查找
node* Search_id(int id, node* L)
{
node* p = L;
while (p->next != NULL)//如果在链表中查找,一直找,
{
if (p->next->ID == id)
{
return p;
}
p = p->next;
}
return NULL;
}
// 按姓名进行查找
node* Search_name(char name[], node* L)
{
node* p = L;
while (p->next != NULL)
{
if (strcmp(name, p->next->Name) == 0)
{
return p;
}
p = p->next;
}
return NULL;
}
// 输出学生信息
void Print(node* L)
{
system("cls");
node* p = L->next;
Print_Printf();
if (p != NULL)
{
while (p != NULL)
{
printf("________________________________________________________________\n");
printf("|%d\t |%s\t |%s\t |%s\t |%s\t |%d\t |\n", p->ID, p->Name, p->Sex, p->Class, p->Room, p->Score);
printf("________________________________________________________________\n");
p = p->next;
}
//fflush(p);
}
}
void Print_Printf()//表格
{
printf("________________________________________________________________\n");
printf("|学号\t|姓名\t|性别\t|班级\t\t|宿舍号\t\t|成绩\t|\n");
printf("________________________________________________________________\n");
}
// 排序学生信息
void Sort(node* L)//排序这里主要还是注意链表的交换,涉及到数据域的交换与指针域的交换。
{
system("cls");
int choice = 0;
printf("\033[33m\033[39m按照学号从大到小排序 ---- 1\n");
printf("按照学号从小到大排序 ---- 2\n");
printf("按照成绩从大到小排序 ---- 3\n");
printf("按照成绩从小到大排序 ---- 4\n");
printf("请选择排序方式:");
scanf("%d", &choice);
int flag = 0;
for (node* p = L->next; p != NULL; p = p->next)//p指向头节点的下一个节点,但是不等于空,那么p就是p的下一个节点
{
for (node* q = p; q != NULL; q = q->next)//q指向p,但是不等于空,那么q就是q的下一个节点
{
switch (choice)
{
case 1:
if (!cmp_big_ID(*p, *q))
{
flag = 1;
}
break;
case 2:
if (!cmp_small_ID(*p, *q))
{
flag = 1;
}
break;
case 3:
if (!cmp_big_Score(*p, *q))
{
flag = 1;
}
break;
case 4:
if (!cmp_small_Score(*p, *q))
{
flag = 1;
}
break;
}
if (flag == 1)
{
// 交换数据域
node t = *p;
*p = *q;
*q = t;
// 处理指针域
t.next = p->next;//t的下一个节点就是p的下一个节点
p->next = q->next;//p的下一个节点就是q的下一个节点
q->next = t.next;//q的下一个节点就是他的下一个节点
flag = 0;
}
}
}
}
// 学号从大到小
bool cmp_big_ID(node e1, node e2)
{
return e1.ID > e2.ID;
}
// 成绩从大到小
bool cmp_big_Score(node e1, node e2)
{
return e1.Score > e2.Score;
}
// 学号从小到大
bool cmp_small_ID(node e1, node e2)
{
return e1.ID < e2.ID;
}
// 成绩从小到大
bool cmp_small_Score(node e1, node e2)
{
return e1.Score < e2.Score;
}
// 退出管理系统
void goodbye()
{
system("cls");
printf("欢迎下次使用学生信息管理系统!");
//exit(0);// 结束程序
}
// 修改学生信息
void Fix1(node* L)//这是学生修改资料的功能与管理员功能一样。只是比管理员的少几个功能
{
system("cls");
int id;
printf("请输入要修改的学生的学号:");
scanf("%d", &id);
node* st = Search_id(id, L);
if (st == NULL)
{
printf("查无此人!\n");
return;
}
st = st->next;
int choice = 0;
while (1)
{
system("cls");
// 输出一次所要修改的学生成绩
printf("________________________________________________________________\n");
printf("|学号\t|姓名\t|性别\t|班级\t\t|宿舍号\t\t|成绩\t|\n");
printf("________________________________________________________________\n");
printf("|%d\t |%s\t |%s\t |%s\t |%s\t |%d\t |\n", st->ID, st->Name, st->Sex, st->Class, st->Room, st->Score);
printf("________________________________________________________________\n");
printf("修改姓名 ---- 1\n");
printf("修改性别 ---- 2\n");
printf("请输入要修改的信息:");
scanf("%d", &choice);
switch (choice)
{
case 1:
printf("请输入姓名:");
scanf("%s", st->Name);
break;
case 2:
printf("请输入性别:");
scanf("%s", st->Sex);
break;
}
printf("是否继续修改该学生信息?(Yes:1 / No:0):");
scanf("%d", &choice);
if (choice == 0)
{
break;
}
}
// 修改完成后该学生的信息
printf("________________________________________________________________\n");
printf("|学号\t|姓名\t|性别\t|班级\t\t|宿舍号\t\t|成绩\t|\n");
printf("________________________________________________________________\n");
printf("|%d\t |%s\t |%s\t |%s\t |%s\t |%d\t |\n", st->ID, st->Name, st->Sex, st->Class, st->Room, st->Score);
printf("________________________________________________________________\n");
// 保存信息
Save_FILE(L);
}
void M_Clear(node* L)
{
//system("cls");
node* p = L->next;
Print_Printf();
if (p != NULL)
{
while (p != NULL)
{
free(p);
p= p->next;
}
}
}
void grcx(node* L)//这是学生查询功能,
{
int id;
char name[50];
node* st;
printf("请输入要查询的姓名:");
scanf("%s", name);
st = Search_name(name, L);
if (st == NULL)
{
printf("查无此人!\n");
}
else
{
st = st->next;
printf("\033[33m\033[36m________________________________________________________________\n");
printf("|学号\t|姓名\t|性别\t|班级\t\t|宿舍号\t\t|成绩\t|\n");
printf("________________________________________________________________\n");
printf("|%d\t |%s\t |%s\t |%s\t |%s\t |%d\t |\n", st->ID, st->Name, st->Sex, st->Class, st->Room, st->Score);
printf("________________________________________________________________\n");
}
}
main.c文件
#include "mystdio.h"
#include "111.h"
// 读取文件
int Read_FILE(node* L);
// 保存文件
int Save_FILE(node* L);
node list;// 链表
int main()
{
S://goto标志位
mima();//界面
int i;
printf("\n");
printf("\033[37m 请选择\n");
printf("\n");
scanf("%d",&i);
switch (i)
{
case 1:
int choice = 0;//定义的一个变量
Read_FILE(&list);//读取文件
while (true)//true是代表真,则执行
{
printf("\033[33m 即将进入管理员界面\n");
sleep(2);
printf(" 请输入管理员密码:");
char root2[256] = "1812";//这是密码
getchar();
C:
GetString(root2);//密码加密函数
printf("\n");
if( strcmp(root2,"1812")==0)//判断如果密码是否一致
{
printf("\n");
printf(" 密码正确 登陆成功\n");
printf("\033[33m\033[37m 即将进入\n");
printf("\n");
sleep(2);//延迟两秒
qq:
welcome();//这是管理员的功能界面
scanf("%d", &choice);
switch (choice)
{
case 1:// 增加学生信息
Add_Printf();
break;
case 2:// 删除学生信息
Delete_Printf(&list);
break;
case 3:// 修改学生信息
Fix(&list);
break;
case 4:// 查询学生信息
Search_Printf(&list);
break;
case 5:// 显示学生信息
Print(&list);
break;
case 6:// 排序学生信息
Sort(&list);
break;
case 7:// 返回界面
//goodbye();
goto S;
break;
case 8:
hidepassword(&list);//修改密码
break;
case 9:
M_Clear(&list);//刷新学生信息
break;
}
printf("是否需要继续操作?(Yes:1 / No:0):");
scanf("%d", &choice);
if (choice == 1)
{
goto qq;
}
else
{
goto qq;
}
}
else
{
printf("\n");
printf(" 密码错误,请重试");
printf("\n");
goto C;
}
while (strcmp(root2,"1812")!=0);
}
break;
case 2:
printf("\n");
printf("\n");
printf("\n");
printf("\n");
printf("\033[33m\033[36m 即将进入学生用户界面\n");
printf("\n");
printf("\n");
printf("\n");
printf("\n");
sleep(2);
int root3 = 1999;//这是用户密码
char root4[256] = "1812";
do
D:
{
printf(" \n");
printf("\033[33m\033[36m 欢迎用户来到学生系统 \n");
printf(" \n");
printf(" \n");
printf("\033[33m\033[36m 请输入帐号和密码 \n");
printf("\n");
printf("账号:");
scanf("%d",&root3);
printf("密码:");
getchar();
GetString(root4);
printf("\n");
if(root3 == 1999 && strcmp(root4,"1812")==0)//账号密码一致则成功进入
{
printf("\n");
printf("\n");
printf("\n");
printf("\n");
printf("\n");
printf(" 登录成功请稍后!\n");
printf("\n");
printf("\n");
printf("\n");
printf("\n");
printf("\n");
sleep(3);
Q:
printf("\n");
printf("\033[33m\033[31m 1,查询个人信息\n");
printf("\n");
printf("\033[33m\033[31m 2,修改个人信息\n");
printf("\n");
printf("\033[33m\033[31m 3,退出\n");
printf("\n");
int q;
int o;
printf(" 请选择\n");
scanf("%d",&q);
switch (q)
{
case 1:
grcx(&list);
goto Q;
break;
case 2:
//int o;
scanf("%d",&o);
printf("\n");
printf("\033[33m\033[39m 请稍候。。。\n");
printf("\n");
printf("\n");
printf("\n");
printf("\n");
sleep(2);
printf("\033[33m\033[39m 请输入\n");
Fix1(&list);
goto Q; //跳转到学生用户功能界面
break;
case 3:
goto S;//总界面
break;
default:
printf("\033[33m\033[37m 输入有误,请重新输入\n");
sleep(2);
goto Q;
break;
}
}
else
{
printf("\033[33m\033[39m******************************************************************************************************************************\n");
printf("\n");
printf("账号密码输入有误\n");
printf("请重新输入\n");
printf("输入1“继续输入” 输入2“直接退出”\n");
int i;
scanf("%d",&i);
switch (i)
{
case 1:
goto D;
break;
case 2:
exit(-1);
default:
break;
}
printf("\n");
}
}while(root3 != 1999 && strcmp(root4,"1812")!=0);
break;
default:
printf("输入有误!请重新输入\n");
sleep(3);
break;
}
return 0;
}
头文件库,我是用的#include "mystdio.h",代码如下:
#ifndef __MYHEAD_H__
#define __MYHEAD_H__
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <wait.h>
#include <time.h>
#include <signal.h>
#include <string.h>
#include <strings.h>
#include <sys/wait.h>
#include <dirent.h>
#include <math.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/msg.h>
#include <sys/sem.h>
#include <pthread.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <stdbool.h>
#endif
这就是以上所有代码,写代码流程按照思路来写,,有什么不好,或者有问题,有BUG的可以随时找我。