学生宿舍管理系统
实现功能
1.学生登录注册
2.宿管录入、修改、删除、查询学生信息
一、功能结构
二、代码实现
1.头文件声明需要使用的函数名
代码入下:
//Main.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void PrimaryMenu();
void secondMenu();
void stuMenu();
void admMenu();
void revise();
void Stu_Rev_Menu();
void File_Readable();
int Choice();
struct user Student_Login(void);
void Inf_Rev();
void Stu_Rev1(Stu_ID);
void Stu_Rev2(Stu_ID);
void Qurey();
void Search_infor1();
void Search_infor2();
void Search_infor3();
void getInform();
void Register();
void Delet_Infor();
void Rev_Class();
2.打印各个选项菜单函数
代码如下:
//PrimaryMenu.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void PrimaryMenu()
{
printf("-----欢迎使用学生宿舍管理系统-----\n");
printf("------------您的身份--------------\n");
printf("-------------1.学生---------------\n");
printf("-------------2.宿管---------------\n");
printf("-------------0.退出---------------\n");
printf("----------------------------------\n");
};
void secondMenu()
{
printf("-------------1.登录---------------\n");
printf("-------------2.注册---------------\n");
printf("-------------0.返回---------------\n");
}
void stuMenu()
{
printf("------您的操作------\n");
printf("-------1.请假-------\n");
printf("-------2.报修-------\n");
printf("-------0.返回-------\n");
printf("--------------------\n");
};
void admMenu()
{
printf("------您的操作------\n");
printf("---1.查询学生信息---\n");
printf("---2.搜索学生信息---\n");
printf("---3.录入学生信息---\n");
printf("---4.修改学生信息---\n");
printf("---5.删除学生信息---\n");
printf("---0.返回-----------\n");
};
void revise()
{
printf("------修改信息------\n");
printf("-------1.姓名-------\n");
printf("-------2.班级-------\n");
printf("------3.宿舍号------\n");
printf("-------4.床位-------\n");
printf("-------5.报修-------\n");
printf("-------6.请假-------\n");
}
void Stu_Rev_Menu()
{
printf("-------1.报修-------\n");
printf("-------2.请假-------\n");
}
void Rev_Class()
{
printf("------分类查询------\n");
printf("-------1.学号-------\n");
printf("------2.宿舍号------\n");
printf("-------3.班级-------\n");
}
3.选择选项函数
代码入下:
//operate.c
#include<stdio.h>
int Choice()
{
int choice;
printf("请执行操作:");
scanf("%d", &choice);//这里可以加入判定输入选择的限制,例如只能输入1-6数字
return choice;
};
4.判断打开文件是否成功
代码入下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void File_Readable()
{
FILE* fp;
if ((fp = fopen("Register.txt", "rb+")) == NULL) //打开文件出错时,fopen() 将返回一个空指针,也就是 NULL
{
printf("ERROR:FILE CAN'T OPEN");
exit(0);
};
if ((fp = fopen("StuInform.txt", "rb+")) == NULL)
{
printf("ERROR:FILE CAN'T OPEN");
exit(0);
};
fclose(fp);
}
5.创建结构体
创建存储学生账号密码与学生信息的结构体
代码入下:
//将结构体的创建放入头文件
#define N 9 //之后修改等功能所用到的新的字符数组长度设定最好与结构体设定得一样
typedef struct student
{
char name[N];//姓名
char num[N];//学号
char class[N]; //班级
char dorm[N]; //宿舍号
char bednum[N]; //床位
int Report_Repair; //报修,0无申请,1申请
int Leave;//请假,同报修
}STU;
typedef struct user
{
char username[20];
char password[20];
}USER;
6.宿管录入学生信息函数
#StuInform.txt存放录入学生的信息
代码入下:
#include"Main.h"
#pragma
void getInform()
{
FILE* fp;
fp = fopen("StuInform.txt", "a+");//a+是在文件末尾进行操作(可读可写),防止已注册的学号被清空
int getNum , i ;//getNum录入学生人数,i循环录入学生信息
printf("请输入录入学生人数:");
scanf("%d", &getNum);
STU a[10];//a[10]更改成文件预计存放结构体数量的数字,这里演示随便写的一个10
for (i = 0; i < getNum;i++)//下列信息录入增加的判定输入内容的条件可修改
{
while (1)
{
printf("请输入学生姓名:");
scanf("%s", a[i].name);
if ((strspn(a[i].name, "abcdefghijklmnopqrstuvwxyz") != strlen(a[i].name)) || strlen(a[i].name) >= 20) //判断是否全是字母
printf("输入错误,请重新输入\n");
else break;
};
while (1)
{
printf("请输入学生学号:");
scanf("%s", a[i].num);
if ((strspn(a[i].num, "0123456789") != strlen(a[i].num)) || strlen(a[i].num) != 8) //判断是否全为数字
printf("输入错误,请重新输入\n");
else break;
};
while (1)
{
printf("请输入班级:");
scanf("%s", a[i].class);
if ((strspn(a[i].class, "0123456789") != strlen(a[i].class)) || strlen(a[i].class) != 6)
printf("输入错误,请重新输入\n");
else break;
};
while (1)
{
printf("请输入宿舍号:");
scanf("%s", a[i].dorm);
if ((strspn(a[i].dorm, "0123456789NS") != strlen(a[i].dorm)) || strlen(a[i].dorm) != 5)
printf("输入错误,请重新输入\n");
else break;
};
while (1)
{
printf("请输入床位:");
scanf("%s", a[i].bednum);
if ((strspn(a[i].bednum, "123456") == strlen(a[i].bednum)) && strlen(a[i].bednum) == 1)
break;
else printf("输入错误,请重新输入\n");
};
a[i].Report_Repair = 0;//录入时,请假报修均初始化为0
a[i].Leave = 0;
fwrite(&a[i], sizeof(STU), 1, fp);
printf("录入成功\n");
};
//fwrite(a, sizeof(STU), getNum, fp);
fclose(fp);
};
效果如下:
7.宿管修改学生信息函数
代码如下:
#include"Main.h"
#define N 9
void Inf_Rev()
{
int i = 0,ii=0,y=0;
char stand_in[N];//需要修改学号
int choice_num;//选择修改内容
char name[N];
char num[N]; //学号
char class[N]; //班级
char dorm[N]; //宿舍号
char bednum[N]; //床位
int Report_Repair; //报修
int Leave;//请假
FILE* fp;
fp = fopen("StuInform.txt", "rb+");
STU a[10];
while (1)
{
if (!feof(fp))//foef函数会在文件最后一个结构体的下一个返回1,所以fread会多读一个空的结构体,这点很重要,所以i要减一,防止内存越界。
{
fread(&a[i], sizeof(STU), 1, fp);
i++;
}
else break;
};
int n = i - 1;//记录文件中有多少个结构体,即有多少已注册的学生,后面全是这种方法记录结构体数量,不再赘述。
fclose(fp);
printf("请输入修改学生的学号:");
scanf("%s", stand_in);
for (ii ; ii < n; ii++)//循环找到需要修改的结构体的下标
{
if (!strcmp(a[ii].num, stand_in))
{
printf("姓名 班级 学号 宿舍号 床位 请假 报修\n");
printf("%s %s %s %s %s %d %d\n", a[ii].name, a[ii].class, a[ii].num, a[ii].dorm,
a[ii].bednum, a[ii].Report_Repair, a[ii].Leave);
break; //打印修改前信息
}
if (ii == n-1)
{
printf("该学生不存在\n");
return;//找不到则退出函数
}
}
revise();//找到需要修改的学生信息,则打印修改菜单
printf("请输入修改内容:");
scanf("%d", &choice_num);
switch (choice_num)
{
case 1: {
do {
printf("请输入修改后学生姓名:");
scanf("%s", name);
if ((strspn(name, "abcdefghijklmnopqrstuvwxyz") != strlen(name)) || strlen(name) >= 20) //判断是否全是字母
printf("输入错误,请重新输入");
else break;
} while (1);
strcpy(a[ii].name, name);//覆盖结构体数组中的原数据
break;
}
case 2: {
do {
printf("请输入修改后班级:");
scanf("%s", class);
if ((strspn(class, "0123456789") != strlen(class)) || strlen(class) != 6)
printf("输入错误,请重新输入");
else break;
} while (1);
strcpy(a[ii].class, class);
break;
}
case 3: {
do {
printf("请输入修改后宿舍号:");
scanf("%s", dorm);
if ((strspn(dorm, "0123456789NS") != strlen(dorm)) || strlen(dorm) != 5)
printf("输入错误,请重新输入");
else break;
} while (1);
strcpy(a[ii].dorm, dorm);
break;
}
case 4: {
do {
printf("请输入修改后床位:");
scanf("%s", bednum);
if ((strspn(bednum, "123456") != strlen(bednum)) || strlen(bednum) != 1)
printf("输入错误,请重新输入\n");
else break;
} while (1);
strcpy(a[ii].bednum, bednum);
break;
}
case 5: {
if (a[ii].Report_Repair == 0)
a[ii].Report_Repair = 1;
else
a[ii].Report_Repair = 0;
}
case 6: {
if (a[ii].Leave == 0)
a[ii].Leave = 1;
else
a[ii].Leave = 0;
}; break;
}
printf("姓名 班级 学号 宿舍号 床位 请假 报修\n");
printf("%s %s %s %s %s %d %d\n", a[ii].name, a[ii].class, a[ii].num, a[ii].dorm,
a[ii].bednum, a[ii].Report_Repair, a[ii].Leave);//打印修改后的信息
fp = fopen("StuInform.txt", "wb+");
for (int x = 0; x < n; x++)
{
fwrite(&a[x], sizeof(STU), 1, fp);
}
fclose(fp);
printf("-----修改成功-----\n");
}
效果如下:
8.宿管删除已录入学生信息
代码如下:
#include"Main.h"
void Delet_Infor()
{
FILE* fp;
fp = fopen("StuInform.txt", "r");
STU a[10];
int i = 0;
int j = 0;
int x = 0;
int m = 0;
char DeletNum[N];
while (1)
{
if (!feof(fp))
{
fread(&a[i], sizeof(STU), 1, fp);
i++;
}
else break;
};
int n = i - 1;
fclose(fp);
printf("---------删除学生信息-----------\n");
printf("请输入删除学生学号:");
scanf("%s", DeletNum);
for (j; j < n; j++)
{
if (!strcmp(a[j].num, DeletNum))
{
fp = fopen("StuInform.txt", "w+");
for (x; x < n; x++)
{
if (x != j)
fwrite(&a[x], sizeof(STU), 1, fp);
}
fclose(fp);
printf("-----------删除成功---------\n");
}
if (strcmp(a[j].num, DeletNum))
m++;
}
if (j == m - 1)
printf("该学生不存在,无法删除\n");
};
效果如下:
删除后:
9.宿管浏览已录入学生信息
#将录入的学生信息全部打印浏览
代码如下:
#include"Main.h"
//查询学生信息
void Qurey()
{
int i = 0,n;
FILE* fp;
fp = fopen("StuInform.txt","r");
if (fp == NULL)
{
printf("未录入学生信息");
return;
};
STU a[100];
printf("姓名 班级 学号 宿舍号 床位 请假 报修\n");
while (1)
{
if (!feof(fp))
{
fread(&a[i], sizeof(STU), 1, fp);
i++;
}
else break;
};
n = i - 1;
for(i=0;i<n;i++)
printf("%s %s %s %s %s %d %d\n",
a[i].name, a[i].class, a[i].num, a[i].dorm, a[i].bednum, a[i].Report_Repair, a[i].Leave);
};
效果如下:
10.宿管搜索已录入学生信息
按班级、宿舍号、学号查找
代码如下:
#include"Main.h"
void Search_infor1()//学号查找
{
STU a[10],b,c[10];
int i = 0,n,m=0;//m判断是否存在该学生
printf("-------------------\n");
printf("请输入搜索学生学号:");
scanf("%s",b.num);
FILE* fp;
fp = fopen("StuInform.txt", "r");
while (1)
{
if (!feof(fp))
{
fread(&a[i], sizeof(STU), 1, fp);
i++;
}
else break;
};
fclose(fp);
fp = fopen("StuInform.txt", "rb");
n = i - 1;
printf("姓名 班级 学号 宿舍号 床位 请假 报修\n");
for (int k = 0; k < n; k++)
{
fread(&c[k], sizeof(STU), 1, fp);
if (!strcmp(c[k].num, b.num))
printf("%s %s %s %s %s %d %d\n", c[k].name, c[k].class, c[k].num, c[k].dorm, c[k].bednum, c[k].Report_Repair, c[k].Leave);
break;
m++;
};
if (n == m)
printf("------------------未搜索到该学生信息-----------------\n");
fclose(fp);
};
void Search_infor2()//宿舍号查找
{
STU a[10], b, c[10];
int i = 0, n, m = 0;//m判断是否存在该学生
printf("-------------------\n");
printf("请输入搜索学生宿舍号:");
scanf("%s", b.dorm);
FILE* fp;
fp = fopen("StuInform.txt", "r");
while (1)
{
if (!feof(fp))
{
fread(&a[i], sizeof(STU), 1, fp);
i++;
}
else break;
};
fclose(fp);
fp = fopen("StuInform.txt", "rb");
n = i - 1;
printf("姓名 班级 学号 宿舍号 床位 请假 报修\n");
for (int k = 0; k < n; k++)
{
fread(&c[k], sizeof(STU), 1, fp);
if (!strcmp(c[k].dorm, b.dorm))
printf("%s %s %s %s %s %d %d\n", c[k].name, c[k].class, c[k].num, c[k].dorm, c[k].bednum, c[k].Report_Repair, c[k].Leave);
else
m++;
};
if (n == m)
printf("------------------未搜索到该学生信息-----------------\n");
fclose(fp);
};
void Search_infor3()//班级查找
{
STU a[10], b, c[10];
int i = 0, n, m = 0;//m判断是否存在该学生
printf("-------------------\n");
printf("请输入搜索学生班级:");
scanf("%s", b.class);
FILE* fp;
fp = fopen("StuInform.txt", "r");
while (1)
{
if (!feof(fp))
{
fread(&a[i], sizeof(STU), 1, fp);
i++;
}
else break;
};
fclose(fp);
fp = fopen("StuInform.txt", "rb");
n = i - 1;
printf("姓名 班级 学号 宿舍号 床位 请假 报修\n");
for (int k = 0; k < n; k++)
{
fread(&c[k], sizeof(STU), 1, fp);//这里可以直接用a[k]查找,脑子抽搐,这里懒得改了
if (!strcmp(c[k].class, b.class))
printf("%s %s %s %s %s %d %d\n", c[k].name, c[k].class, c[k].num, c[k].dorm, c[k].bednum, c[k].Report_Repair, c[k].Leave);
else
m++;
};
if (n == m)
printf("------------------未搜索到该学生信息-----------------\n");
fclose(fp);
};
效果如下:
11.学生注册函数
#使用Register.txt文件储存注册的账号密码信息,账号即学号
代码如下:
#include"Main.h"
void Register()
{
char test[20];//存放输入的密码
FILE* fp;
fp = fopen("Register.txt", "r");
USER a[10],b;
int i = 0;
int n = 0;
int x = 0;
printf("------注册------\n");
while (1)
{
printf("请输入学号:");
scanf("%s", b.username);
if ((strspn(b.username, "0123456789") == strlen(b.username)) && strlen(b.username) == 8)
break;
else printf("学号不存在,请重新输入\n");//判断输入的学号是否规范并储存在b.username中
};
while (1)
{
if (!feof(fp))
{
fread(&a[i], sizeof(STU), 1, fp);
i++;
}
else break;
};
n = i - 1;
fclose(fp);
for (x; x < n; x++)
{
if (!strcmp(a[x].username, b.username))//查询当前需注册的用户名在文件中是否已注册
{
printf("学号已注册,请登录\n");
Register();//递归以重新注册
}
}
fp = fopen("Register.txt", "a+");//a+是在文件末尾进行操作(可读可写),防止已注册的学号被清空
while (1)
{
printf("请输入密码:");
scanf("%s", &b.password);
printf("请确认密码:");
scanf("%s", &test);
if (strcmp(b.password, test))//确认密码
{
printf("密码不匹配,请重新输入\n");
}
else
{
fwrite(&b, sizeof(USER), 1, fp);
printf("注册成功,请登录\n");
fclose(fp);
return;
}
};
};
效果如下:
12.学生登录函数
代码如下:
#include"Main.h"
struct user Student_Login()//建立可以返回结构体的函数,在进行学生操作时会使用到
{
int x = 1;
int i = 0;
int j = 0;
FILE* fp;
fp = fopen("Register.txt", "r");
USER a[10],b;
while (1)
{
if (!feof(fp))
{
fread(&a[i], sizeof(STU), 1, fp);
i++;
}
else break;
};
int n = i - 1;
fclose(fp);
fp = fopen("Register.txt", "r");
while (1)
{
printf("----登录----\n");
printf("请输入学号:");
scanf("%s", b.username);
if ((strspn(b.username, "0123456789") != strlen(b.username)) || strlen(b.username) != 8)
printf("学号不存在,请重新输入\n");
else break;
};
printf("请输入密码:");
scanf("%s", b.password);
for (j =0 ; j < i; j++)
{
fread(&a[j], sizeof(USER), 1, fp);
if (!strcmp(a[j].username, b.username))
{
if (!strcmp(a[j].password, b.password))
{
printf("登录成功\n");
fclose(fp);
return b;//函数结束
}
else
continue;
}
else
continue;
}
printf("账号或密码错误\n");//若循环结束,则没有在文件中找到输入的账号和密码
Student_Login();//重新登录
};
效果如下:
13.学生操作函数
在文件中,以0、1表示学生是否请假或报修
代码入下:
void Stu_Rev1(Stu_ID)//报修
{
int i = 0, ii, y = 0;
FILE* fp;
fp = fopen("StuInform.txt", "r");
STU a[N];
while (1)
{
if (!feof(fp))
{
fread(&a[i], sizeof(STU), 1, fp);
i++;
}
else break;
};
int n = i - 1;
fclose(fp);
for (ii = 0; ii < n; ii++)
{
if (!strcmp(a[ii].num, Stu_ID))
{
printf("姓名 班级 学号 宿舍号 床位 请假 报修\n");
printf("%s %s %s %s %s %d %d\n", a[ii].name, a[ii].class,a[ii].num, a[ii].dorm,
a[ii].bednum, a[ii].Report_Repair, a[ii].Leave);
break;
}
if (ii == n - 1)
{
printf("该学生不存在\n");
return;
}
}
fclose(fp);
if (a[ii].Report_Repair == 0)
a[ii].Report_Repair = 1;
else
a[ii].Report_Repair = 0;
printf("姓名 班级 学号 宿舍号 床位 请假 报修\n");
printf("%s %s %s %s %s %d %d\n", a[ii].name, a[ii].class, a[ii].num, a[ii].dorm,
a[ii].bednum, a[ii].Report_Repair, a[ii].Leave);
fp = fopen("StuInform.txt", "w+");
for (int x = 0; x < n; x++)
fwrite(&a[x], sizeof(STU), 1, fp);
fclose(fp);
printf("---------------------------修改成功--------------------------\n");
}
void Stu_Rev2(Stu_ID)// 请假
{
int i = 0, ii, y = 0;
FILE* fp;
fp = fopen("StuInform.txt", "r");
STU a[N];
while (1)
{
if (!feof(fp))
{
fread(&a[i], sizeof(STU), 1, fp);
i++;
}
else break;
};
int n = i - 1;
fclose(fp);
for (ii = 0; ii < n; ii++)
{
if (!strcmp(a[ii].num, Stu_ID))
{
printf("姓名 班级 学号 宿舍号 床位 请假 报修\n");
printf("%s %s %s %s %s %d %d\n", a[ii].name, a[ii].class, a[ii].num, a[ii].dorm,
a[ii].bednum, a[ii].Report_Repair, a[ii].Leave);
break;
}
if (ii == n - 1)
{
printf("该学生不存在\n");
return;
}
}
fclose(fp);
if (a[ii].Leave == 0)
a[ii].Leave = 1;
else
a[ii].Leave = 0;
printf("姓名 班级 学号 宿舍号 床位 请假 报修\n");
printf("%s %s %s %s %s %d %d\n", a[ii].name, a[ii].class, a[ii].num, a[ii].dorm,
a[ii].bednum, a[ii].Report_Repair, a[ii].Leave);
fp = fopen("StuInform.txt", "wb+");
for (int x = 0; x < n; x++)
fwrite(&a[x], sizeof(STU), 1, fp);
fclose(fp);
printf("---------------------------修改成功--------------------------\n");
}
效果如下:
14.主函数
代码入下:
#include "Main.h"
void main()
{
int choice = 1;
int choice1 = 1;
int choice2 = 1;
int choice3 = 1;
int Test_Num;
char Stu_ID[20];
struct user x;
char* y;
File_Readable();
do{ //do while 循环实现返回上一级的功能
PrimaryMenu();//选择身份,1学生2宿管
choice = Choice();
switch (choice)
{
case 1:do//学生
{
secondMenu();
choice1 = Choice();
switch (choice1)
{
case 1://登录
{
x = Student_Login();
strcpy(Stu_ID, x.username);//登录成功,接收登陆时输入的学号
do {
stuMenu();//打开学生操作目录
choice2 = Choice();
switch (choice2)//执行学生可执行的操作
{
case 1:Stu_Rev1(Stu_ID); break;
case 2:Stu_Rev2(Stu_ID); break;
case 0:Test_Num = 1; break;
default:
break;
}
} while (choice2 != 0);
}; break;
case 2: {
Register(); //注册
x = Student_Login();
strcpy(Stu_ID, x.username);//注册成功后登录
do {
stuMenu();//打开学生操作目录
choice2 = Choice();
switch (choice2)//执行学生可执行的操作
{
case 1:Stu_Rev1(Stu_ID); break;
case 2:Stu_Rev2(Stu_ID); break;
case 0:; break;
default:
break;
};
} while (choice2 != 0); break;
case 0:break;
default:break;
}; break;
}
} while (choice1 != 0); break;
case 2: do { //宿管
admMenu();
choice2 = Choice();
switch (choice2)
{
case 1:Qurey(); break;//查询
case 2: {
Rev_Class();
choice3 = Choice();
switch (choice3) {
case 1:Search_infor1(); break;
case 2:Search_infor2(); break;
case 3:Search_infor3(); break;
}
}; break;//搜索
case 3:getInform(); break;//录入
case 4:Inf_Rev(); break;//修改
case 5:Delet_Infor(); break;//删除
case 0:break;
default:
break;
};
} while (choice2 != 0); break;
case 0:exit(0); break;
default:break;
}
} while (choice != 0);
};
总结
这个系统比较简陋,宿管功能没有人员使用限制,学生信息浏览没有自动排序,输入信息的限制比较少(学号可以录入重复的等等,但是注册我加了判断重复的功能)。总的来说,代码重复度很高,实现得比较复杂,但是这是我初学C语言写的第一个系统,还望海涵,希望能给其他小伙伴带来帮助,如需交流,可私信谢谢~~~~~源代码下载可访问https://github.com/TiAmo-one/Student-dormitory-management-system