一、功能概述
1.账号的登录与注册
2.学生信息的增添
3.学生信息对于学号的排序
4.学生信息的删除
5.学生信息的修改
6.学生信息的查找
7.学生信息的分类
8.学生信息表的打印
9.结束程序时对信息的在内存中的保存
10.执行程序时对保存在内存当中的信息的读取
11.构建菜单
二、流程图
三、功能实现详解
1.文件信息的读取与保存
void saveInfoToFile(char* fileName, InfoSys* pc)
{
FILE* fp = fopen(fileName,"w");
if (fp == NULL)
{
perror("fopen");
return;
}
InfoSys* cur =pc->next;
while (cur)
{
fprintf(fp, "%s %s %s %d %lf %s %s\n", cur->ID, cur->name, cur->sex,
cur->age, cur->score, cur->professional, cur->clas);
cur = cur->next;
}
fclose(fp);
fp = NULL;
return;
}
void readInfoFromFile(char* fileName, InfoSys* pc)
{
FILE* fp = fopen(fileName,"r");
int ch=fgetc(fp);
if (ch == EOF)
{
return;
}
fseek(fp,0,SEEK_SET);
if (fp == NULL)
{
perror("fopen");
return;
}
InfoSys* temp = (InfoSys*)malloc(sizeof(InfoSys));
InfoSys* cur = pc;
cur->next = NULL;
pc->next = cur;
while (fscanf(fp, "%s %s %s %d %lf %s %s", temp->ID, temp->name, temp->sex,
&(temp->age), &(temp->score), temp->professional,
temp->clas) != EOF)
{
InfoSys* next = (InfoSys*)malloc(sizeof(InfoSys));
next->next = NULL;
cur->next = next;
cur = next;
strcpy(cur->ID, temp->ID);
strcpy(cur->name, temp->name);
strcpy(cur->sex, temp->sex);
cur->age = temp->age;
cur->score = temp->score;
strcpy(cur->professional, temp->professional);
strcpy(cur->clas, temp->clas);
//这一块空间是被需要的,不用free;
}
fclose(fp);
fp = NULL;
free(temp);
temp = NULL;
return;
}
2.账号的登录与注册
可以实现对注册账号在文件中的保存和读取,在登录时,实现掩码操作
int isUserValid(char* userAccount, char* userPassword)
{
FILE* fp = fopen("UserInfo.txt","r");
char UAt[USERACCOUNTNUM];
char UPd[USERPASSWORDNUM];
char temp[USERPASSWORDNUM];
if (fgetc(fp) == EOF)
{
printf("无此账号,请重新输入.....\n");
fclose(fp);
fp = NULL;
return 0;
}
fseek(fp,-1,SEEK_CUR);
while (strcmp(fgets(UAt, USERACCOUNTNUM, fp), userAccount) != 0)
{
fgets(temp, USERACCOUNTNUM, fp);
if (fgetc(fp)==EOF)
{
printf("无此账号,请重新输入.....\n");
fclose(fp);
fp = NULL;
return 0;
}
else
{
fseek(fp, -1, SEEK_CUR);
}
}
if (strcmp(UAt, userAccount) == 0)
{
fgets(UPd, USERPASSWORDNUM, fp);
if((strcmp(UPd, userPassword) == 0))
{
printf("\t\t欢迎进入管理系统,请稍后......\n");
Sleep(1000);
fclose(fp);
fp = NULL;
return 1;
}
else
{
printf("密码输入错误,请重新输入......\n");
fclose(fp);
fp = NULL;
return 0;
}
}
}
void enroll_menu()
{
head_menu();
printf("\n\n\n");
printf("\t\t用户注册,请输入账号、密码......\n\n");
}
void login_menu()
{
head_menu();
printf("\n\n\n");
printf("\t\t用户登录,请输入账号、密码......\n\n");
return;
}
void enroll()
{
FILE* fp = fopen("UserInfo.txt","a");
char userAccount[USERACCOUNTNUM];
char userPassword[USERPASSWORDNUM];
if (fp == NULL)
{
perror("fopen");
return;
}
getchar();
enroll_menu();
printf("\t\t账号:>");
int i;
for (i = 0; i < USERACCOUNTNUM; i++)
{
userAccount[i] = getchar();
if (userAccount[i] == '\n')
{
break;
}
}
userAccount[i] = '\0';
printf("\t\t密码:>");
for (i = 0; i < USERPASSWORDNUM; i++)
{
userPassword[i] = getchar();
if (userPassword[i] == '\n')
{
break;
}
}
userPassword[i] = '\0';
fprintf(fp,"%s",userAccount);
fputc('\n',fp);
fprintf(fp,"%s",userPassword);
fputc('\n\n\n', fp);
printf("\n\n注册成功.....");
printf("\n\n请退出程序重新运行......");
Sleep(1000);
fclose(fp);
fp = NULL;
}
int login()
{
char userPassword[USERPASSWORDNUM], userAccount[USERACCOUNTNUM];
int i;
/*login_menu();*/
getchar();
printf("\t\t账号:>");
for (i = 0; i < USERACCOUNTNUM; i++)
{
userAccount[i] =getchar();
if (userAccount[i] == '\n')
{
break;
}
}
userAccount[++i] = '\0';
printf("\t\t密码:>");
for (i = 0; i < USERPASSWORDNUM; i++)
{
userPassword[i] = _getch();
if (userPassword[i] == '\r')//回车
{
break;
}
printf("*");//掩码处理
}
userPassword[i] = '\n';
userPassword[++i] = '\0';
if (isUserValid(userAccount, userPassword) == 1)
{
return 1;
}
else
{
return 0;
}
}
3.菜单的构建(为了方便对基础功能的种类的了解,先说菜单)
以下包括了登录菜单和选择菜单,下文出现的功能如图所示
void welcome_menu()
{
printf("\n\n\n");
printf("\t ╔═════════════╗\n");
printf("\t ║ (\\ (\\ ║\n");
printf("\t ║ (-。-) ║\n");
printf("\t ║ 。_(\") ║\n");
printf("\t ╚═════════════╝\n");
printf("\t *欢迎使用信息管理系统*\n");
printf("\t ····SWPU猪皮兄弟为你服务····\n");
printf("\n\n\n");
system("pause");
}
void main_menu()
{
printf("\t\t| * * * * * * * 信息管理系统 * * * * * * |\n");
printf("\t\t|……………………………………………………|\n");
printf("\t\t| 请选择操作菜单序号(0-6) |\n");
printf("\t\t|……………………………………………………|\n");
printf("\t\t| 1----学生信息录入 |\n");
printf("\t\t| 2----学生信息排序 |\n");
printf("\t\t| 3----学生信息查询 |\n");
printf("\t\t| 4----学生分类查询 |\n");
printf("\t\t| 5----学生信息删除 |\n");
printf("\t\t| 6----学生信息修改 |\n");
printf("\t\t| 7----学生信息打印 |\n");
printf("\t\t| 0---- 退 出 |\n");
printf("\t\t|……………………………………………………|\n");
printf("\t\t| * * * * * * * * * * * * * * * * * * * |\n");
printf("\n\t请选择序号: ");
}
4.学会信息管理的基础操作(增删查改、打印列表、排序)
对这部分的实现,采用的是单链表的结构
1.打印列表和退出程序
void showMessge(InfoSys * pc)
{
printf(" ~~~~~ 学生信息表 ~~~~~\n");
printf(" ---------------------------------------------------------------------------------------\n");
printf("%-12s\t%-9s\t%-4s\t%-4s\t%-9s\t%-9s\t%-7s\n","学号","姓名","性别","年龄","成绩","专业","班级");
InfoSys* cur = pc->next;
while (cur!=NULL)
{
printf("%-12s\t%-9s\t%-4s\t%-4d\t%-9.2lf\t%-9s\t%-7s\n", cur->ID, cur->name,
cur->sex, cur->age, cur->score, cur->professional, cur->clas);
cur = cur->next;
}
return;
}
void Exit()
{
exit(-1);
}
2.增添学生信息
void Add(InfoSys* pc)
{
InfoSys* cur = pc->next;
char ID[IDNUM];
char name[NAMENUM];
char sex[SEXNUM];
int age;
double score;
char professional[PROFESSIONALNUM];
char clas[CLASNUM];
while(1)
{
printf("请依次输入:> 学号 - 姓名 - 性别 - 年龄 - 成绩 - 专业 - 班级\n");
scanf("%s %s %s %d %lf %s %s", ID, name, sex, &age, &score, professional, clas);
InfoSys* newnode = CreateNode(ID, name, sex, age, score, professional, clas);
if (cur == NULL)
{
pc->next = newnode;
}
else
{
while (cur->next != NULL)
{
cur = cur->next;
}
cur->next = newnode;
}
printf("请选择是否继续添加:>(Y/N)\n");
char input;
rewind(stdin);//让下面的scanf不受缓存区的影响
scanf("%c",&input);//这里的scanf直接跳过的问题,用以上方法
if (input == 'Y')
{
continue;
}
else
{
break;
}
}
return;
}
注意一定要在第二个scanf之前rewind(stdio),不然这个scanf会读取缓冲区里面的\n就等于是直接跳过。
3.删除学生信息
void Del(InfoSys* pc)
{
InfoSys* cur = pc->next;
InfoSys* prev = pc;
char ID[IDNUM] = { 0 };
printf("请输入要删除学生的学号: \n");
int count = 0;
scanf("%s",ID);
while (cur)
{
if (strcmp(cur->ID, ID) == 0)
{
prev->next=cur->next;
free(cur);
count++;
cur = NULL;
}
else
{
cur = cur->next;
prev = prev->next;
}
}
if (count == 0)
{
printf("未找到该学生信息......\n");
system("pause");
return;
}
printf("删除成功......\n");
return;
}
4.对学生信息进行排序(这里采用冒泡排序的思想)
void Sort(InfoSys* pc)//实际中都是按学号排序//代码未实现,需要多次进行排序操作
{
InfoSys* prev, * cur, * next;
int count=0;
cur = pc->next;
while (cur != NULL)
{
count++;
cur = cur->next;
}
if (count == 1)
{
printf("排序成功......\n");
return;
}
else if (count == 0)
{
printf("列表中无学生信息\n");
return;
}
else
{
for (int i = 0; i < count-1; i++)
{
prev = pc;
cur = pc->next;
next = cur->next;
while (next != NULL)
{
if (strcmp(cur->ID, next->ID) > 0)
{
cur->next = next->next;
prev->next = next;
next->next = cur;
next = cur->next;
prev = prev->next;
}
else
{
next = next->next;
cur = cur->next;
prev = prev->next;
}
}
}
}
printf("排序成功......\n");
return;
}
5.查询与分类查询
普通查询(按学号进行查找)
void Search(InfoSys* pc)
{
printf("请输入要查找学生的学号\n");
char ID[IDNUM] = { 0 };
InfoSys* cur = pc->next;
int count = 0;
scanf("%s",ID);
printf(" ~~~~~ 学生信息表 ~~~~~\n");
printf(" ---------------------------------------------------------------------------------------\n");
printf("%-12s\t%-9s\t%-4s\t%-4s\t%-9s\t%-9s\t%-7s\n", "学号", "姓名", "性别", "年龄", "成绩", "专业", "班级");
while (cur != NULL)
{
if (strcmp(cur->ID, ID) == 0)
{
printf("%-12s\t%-9s\t%-4s\t%-4d\t%-9.2lf\t%-9s\t%-7s\n", cur->ID, cur->name, cur->sex, cur->age, cur->score, cur->professional, cur->clas);
count++;
}
cur = cur->next;
}
if(count ==0)
printf("未找到该学生信息......\n");
return;
}
分类查询
void ClassifySearch(InfoSys* pc)
{
printf(" 学生分类......\n");
printf("------------------------------------------------------\n");
printf("1.姓名 2.性别 3.年龄 4.成绩 5.专业 6.班级\n");
printf("请输入要分的类型(1-6):\n");
int input;
scanf("%d",&input);
switch (input)
{
case 1:
{
printf("请输入需要查找的姓名:");
char name[NAMENUM] = { 0 };
scanf("%s", name);
InfoSys* cur = pc->next;
if (cur == NULL)
{
printf("未查询到相关信息......\n");
break;
}
printf(" ~~~~~ 学生信息表 ~~~~~\n");
printf(" ---------------------------------------------------------------------------------------\n");
printf("%-12s\t%-9s\t%-4s\t%-4s\t%-9s\t%-9s\t%-7s\n", "学号", "姓名", "性别", "年龄", "成绩", "专业", "班级");
while (cur != NULL)
{
if (strcmp(cur->name, name) == 0)
{
printf("%-12s\t%-9s\t%-4s\t%-4d\t%-9.2lf\t%-9s\t%-7s\n", cur->ID, cur->name, cur->sex, cur->age, cur->score, cur->professional, cur->clas);
}
cur = cur->next;
}
break;
}
case 2:
{
printf("请输入需要查找的姓别:");
char sex[SEXNUM] = { 0 };
scanf("%s", sex);
InfoSys* cur = pc->next;
if (cur == NULL)
{
printf("未查询到相关信息......\n");
break;
}
printf(" ~~~~~ 学生信息表 ~~~~~\n");
printf(" ---------------------------------------------------------------------------------------\n");
printf("%-12s\t%-9s\t%-4s\t%-4s\t%-9s\t%-9s\t%-7s\n", "学号", "姓名", "性别", "年龄", "成绩", "专业", "班级");
while (cur != NULL)
{
if (strcmp(cur->sex, sex) == 0)
{
printf("%-12s\t%-9s\t%-4s\t%-4d\t%-9.2lf\t%-9s\t%-7s\n", cur->ID, cur->name, cur->sex, cur->age, cur->score, cur->professional, cur->clas);
}
cur = cur->next;
}
break;
}
case 3:
{
printf("请输入需要查找的年龄:");
int age;
scanf("%d", &age);
InfoSys* cur = pc->next;
if (cur == NULL)
{
printf("未查询到相关信息......\n");
break;
}
printf(" ~~~~~ 学生信息表 ~~~~~\n");
printf(" ---------------------------------------------------------------------------------------\n");
printf("%-12s\t%-9s\t%-4s\t%-4s\t%-9s\t%-9s\t%-7s\n", "学号", "姓名", "性别", "年龄", "成绩", "专业", "班级");
while (cur != NULL)
{
if (cur->age == age)
{
printf("%-12s\t%-9s\t%-4s\t%-4d\t%-9.2lf\t%-9s\t%-7s\n", cur->ID, cur->name, cur->sex, cur->age, cur->score, cur->professional, cur->clas);
}
cur = cur->next;
}
break;
}
case 4:
{
printf("请输入需要查找的成绩:");
double score;
scanf("%lf", &score);
InfoSys* cur = pc->next;
if (cur == NULL)
{
printf("未查询到相关信息......\n");
break;
}
printf(" ~~~~~ 学生信息表 ~~~~~\n");
printf(" ---------------------------------------------------------------------------------------\n");
printf("%-12s\t%-9s\t%-4s\t%-4s\t%-9s\t%-9s\t%-7s\n", "学号", "姓名", "性别", "年龄", "成绩", "专业", "班级");
while (cur != NULL)
{
if (cur->score == score)
{
printf("%-12s\t%-9s\t%-4s\t%-4d\t%-9.2lf\t%-9s\t%-7s\n", cur->ID, cur->name, cur->sex, cur->age, cur->score, cur->professional, cur->clas);
}
cur = cur->next;
}
break;
}
case 5:
{
printf("请输入需要查找的专业:");
char professional[PROFESSIONALNUM] = { 0 };
scanf("%s", professional);
InfoSys* cur = pc->next;
if (cur == NULL)
{
printf("未查询到相关信息......\n");
break;
}
printf(" ~~~~~ 学生信息表 ~~~~~\n");
printf(" ---------------------------------------------------------------------------------------\n");
printf("%-12s\t%-9s\t%-4s\t%-4s\t%-9s\t%-9s\t%-7s\n", "学号", "姓名", "性别", "年龄", "成绩", "专业", "班级");
while (cur != NULL)
{
if (strcmp(cur->professional, professional) == 0)
{
printf("%-12s\t%-9s\t%-4s\t%-4d\t%-9.2lf\t%-9s\t%-7s\n", cur->ID, cur->name, cur->sex, cur->age, cur->score, cur->professional, cur->clas);
}
cur = cur->next;
}
break;
}
case 6:
{
printf("请输入需要查找的班级:");
char clas[CLASNUM] = { 0 };
scanf("%s", clas);
InfoSys* cur = pc->next;
if (cur == NULL)
{
printf("未查询到相关信息......\n");
break;
}
printf(" ~~~~~ 学生信息表 ~~~~~\n");
printf(" ---------------------------------------------------------------------------------------\n");
printf("%-12s\t%-9s\t%-4s\t%-4s\t%-9s\t%-9s\t%-7s\n", "学号", "姓名", "性别", "年龄", "成绩", "专业", "班级");
while (cur != NULL)
{
if (strcmp(cur->clas, clas) == 0)
{
printf("%-12s\t%-9s\t%-4s\t%-4d\t%-9.2lf\t%-9s\t%-7s\n", cur->ID, cur->name, cur->sex, cur->age, cur->score, cur->professional, cur->clas);
}
cur = cur->next;
}
break;
}
default:
printf("输入错误,正在跳回选择界面......\n");
Sleep(10);
break;
}
}
稍微有点繁琐,可以改进,这里就没有去改进了
另外,查询和分类查询也可以合在一起
6.学生信息的修改
void Modify(InfoSys* pc)
{
char ID[IDNUM] = { 0 };
int count = 0;
InfoSys* cur = pc->next;
printf("请输入修改学生学号;\n");
scanf("%s",ID);
while (cur != NULL)
{
if (strcmp(cur->ID, ID) == 0)
{
printf("已找到该学生信息......\n");
count++;
printf("%-12s\t%-9s\t%-4s\t%-4s\t%-9s\t%-9s\t%-7s\n", "学号", "姓名", "性别", "年龄", "成绩", "专业", "班级");
printf("%-12s\t%-9s\t%-4s\t%-4d\t%-9.2lf\t%-9s\t%-7s\n", cur->ID, cur->name, cur->sex, cur->age, cur->score, cur->professional, cur->clas);
break;
}
cur = cur->next;
}
if (count == 0)
{
printf("未找到修改学生信息.....\n");
return;
}
printf("进行修改操作.....\n");
printf("请依次输入:> 学号 - 姓名 - 性别 - 年龄 - 成绩 - 专业 - 班级\n");
scanf("%s %s %s %d %lf %s %s", cur->ID, cur->name, cur->sex, &(cur->age), &(cur->score), cur->professional, cur->clas);
//age是个整数类型,需要&,而其他的是字符串,变量名就是首地址
Sleep(10);
printf("修改成功\n");
return;
}
四、测试结果
1.系统页面以及账号登录与注册
实现掩码
2.选择菜单
3.基础功能的实现
在这里就不一个个演示了
全部程序放在下面的链接里了,请自行查看
2022.4.20程序设计项目 · 朱毅峰/zhupiC - 码云 - 开源中国 (gitee.com)https://gitee.com/zhu-pi/zhupi-c/tree/master/2022.4.20%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1%E9%A1%B9%E7%9B%AE