前言
前一篇在这:C语言课程设计||学生管理系统(简单版,超详细,看这一篇就够了)
时隔十个月我回来了!!也不干嘛,就把之前那个学生管理系统完善一下,主要是增加了注册和登录功能,依旧用的是Clion。好了直接上代码。(和之前学生信息一样,用了链表)
注册
//注册
void singUp(struct User* headUser){
char newPassword1[20];
char newPassword2[20];
char acc[20];
struct user data;
printf("请输入注册用户名:");
scanf("%s",acc);
struct User* posUser = headUser;
while(posUser)
{
if(strcmp(posUser -> data.acc,acc) == 0)
{
break;
}
posUser = posUser -> next;
}
if(posUser == NULL){
strcpy(data.acc,acc);
do {
printf("请输入密码:");
scanf("%s",newPassword1);
printf("请再次输入密码:");
scanf("%s",newPassword2);
if (strcmp(newPassword1,newPassword2) != 0)
printf("两次密码不相同,请重新输入.......\n");
}while (strcmp(newPassword1,newPassword2) != 0);
strcpy(data.password,newPassword1);
struct User* newUser = createUserNode(data);
newUser -> next = headUser -> next;
headUser -> next = newUser;
printf("注册成功!");
return;
}
else {
printf("该用户名存在,请重新注册......\n");
return;
}
登录
可用*号隐藏,可退格(挺简陋的我感觉)
原理可以看我的这篇:C语言密码*隐藏(可退格)
//登录
void longIn(struct User* headUser){
int k = 3;
int i = 0;
int p = 0;
char str[20] = "\0";
struct user data;
printf("请输入用户名:");
scanf("%s",data.acc);
struct User* posUser = headUser -> next;
while(posUser)
{
if(strcmp(posUser -> data.acc,data.acc) == 0) break;
posUser = posUser -> next;
}
if(posUser == NULL) {
printf("用户不存在......");
return;
}
else {
printf("请输入密码:");
for (k = 3; k > 0;) {
int n = 0;
while ((data.password[n] = getch()) != 13) {
if (data.password[n] == 8) {
n--;
system("cls");
longinAndSingup();
printf("1\n");
printf("----------------【登录】----------------\n");
printf("请输入用户名:");
printf("%s\n", data.acc);
printf("请输入密码:");
for (int j = 0; j < n; j++) {
printf("*");
}
continue;
}
printf("*");
n++;
}
for(i = 0; i < n; i++){
str[i] = data.password[i];
}
str[i] = '\0';//转字符串
if(strcmp(posUser -> data.password,str) == 0)
p = 1;
if (p == 1) {
printf("登录成功!");
system("pause");
system("cls");
list = createList();
readInFromFile(list, "student.txt");
while (1) {
menu();
keyDown();
system("pause");
system("cls");
}
}
else {
k--;
if (k == 0) {
printf("\n您输入密码三次错误,为您自动退出....");
system("pause");
exit(0);
}
printf("\n密码错误,您还有%d次机会\n", k);
system("pause");
system("cls");
longinAndSingup();
printf("1\n");
printf("----------------【登录】----------------\n");
printf("请输入用户名:");
printf("%s\n", data.acc);
printf("请输入密码:");
p = 0;
}
}
}
}
完整代码
登录的用户名和密码存在user.txt
大家可以自己先找一些实例放在文件里
也可以在注册的时候存放进文件里
/*
设计一个学生通讯管理系统,学生信息包括职学号、姓名、班级、住址、电话、QQ等,其中学号不重复。该系统具有以下功能:
(1)学生通讯信息录入(储存在文件中);
(2)学生通讯信息浏览;
(3)查询功能:包括按学号查询、按姓名查询,按班级查询;
(4)学生通讯信息删除:按学号删除、按姓名删除;
(5)学生通讯信息修改:按学号修改、按姓名修改;
(6)学生通讯信息排序:按学号升序、按学号降序;
(7)学生通讯信息统计:统计各班人数、统计各省份人数;
*
*/
//课程设计(学生通讯管理系统)
#include<stdio.h>
#include <stdlib.h>
#include <string.h>
#include<conio.h>
#define N 6 //班级个数
#define K 3 //登录可用次数
//
// Created by 等等 on 2023/12/25.
void longinAndSingup();
void menu();
void keyDown();
void keydown1();
void keydown2();
void keydown3();
void keydown4();
void keydown5();
struct Node* list = NULL;
struct User* user = NULL;
//数据设计
struct student{
int num;
char name[20];
int class;
char addr[50];
char tel[20];
char QQ[50];
};
struct user{
char acc[20];
char password[20];
};
//菜单
void menu(){
printf("************【欢迎来到学生通讯录管理系统】**********\n");
printf("****************************************************\n");
printf("*\t\t1.学生通讯信息录入 *\n");
printf("*--------------------------------------------------*\n");
printf("*\t\t2.学生通讯信息浏览 *\n");
printf("*--------------------------------------------------*\n");
printf("*\t\t3.查询功能 *\n");
printf("*--------------------------------------------------*\n");
printf("*\t\t4.学生通讯信息删除 *\n");
printf("*--------------------------------------------------*\n");
printf("*\t\t5.学生通讯信息修改 *\n");
printf("*--------------------------------------------------*\n");
printf("*\t\t6.学生通讯信息排序 *\n");
printf("*--------------------------------------------------*\n");
printf("*\t\t7.学生通讯信息统计 *\n");
printf("*--------------------------------------------------*\n");
printf("*\t\t0.退出系统 *\n");
printf("****************************************************\n");
}
struct User{
struct user data;
struct User *next;
};
struct Node{
struct student data;
struct Node *next;
};
//创建表
struct Node *createList(){
struct Node* headNode = (struct Node*)malloc(sizeof(struct Node));
headNode->next = NULL;
return headNode;
}
struct User *createUser(){
struct User* headUser = (struct User*)malloc(sizeof(struct User));
headUser->next = NULL;
return headUser;
}
//创建结点
struct Node *createNode(struct student data){
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = data;
newNode->next = NULL;
return newNode;
}
struct User *createUserNode(struct user data){
struct User* newUser = (struct User*)malloc(sizeof(struct User));
newUser->data = data;
newUser->next = NULL;
return newUser;
}
//录入
void insertNodeByHead(struct Node* headNode,struct student data){
struct Node* newNode = createNode(data);
newNode->next = headNode->next;
headNode->next = newNode;
}
void insertUserByHead(struct User* headUser,struct user data){
struct User* newUser = createUserNode(data);
newUser->next = headUser->next;
headUser->next = newUser;
}
//浏览
void printList(struct Node* headNode){
struct Node* pMove = headNode->next;
printf("学号\t姓名\t班级\t地址\t电话\t\tQQ\n");
while (pMove){
printf("%d\t%s\t%d\t%s\t%s\t%s\n",pMove->data.num,pMove->data.name,pMove->data.class,pMove->data.addr,pMove->data.tel,pMove->data.QQ);
pMove = pMove->next;
}
printf("\n");
}
//按学号删除
void deleteNumNode(struct Node* headNode,int num){
struct Node* posNode = headNode -> next;
struct Node* posFrontNode = headNode;
while(posNode -> data.num != num)
{
posFrontNode = posNode;
posNode = posNode -> next;
}
if(posNode == NULL){
printf("未找学号位置,无法删除!");
return;
}
else{
posFrontNode -> next = posNode -> next;
free(posNode);
printf("删除成功!");
}
}
//按名字删除
void deleteNameNode(struct Node* headNode,char *name){
struct Node* posNode = headNode -> next;
struct Node* posFrontNode = headNode;
if(posNode == NULL){
printf("名字不存在,无法删除!\n ");
return;
}
while(strcmp(posNode -> data.name,name))
{
posFrontNode = posNode;
posNode = posNode -> next;
}
if(posNode == NULL){
printf("未找名字位置,无法删除!");
return;
}
else{
posFrontNode -> next = posNode -> next;
free(posNode);
printf("删除成功!");
}
}
//按学号查询
void searchInfoByNum(struct Node* headNode,int num){
struct Node* pMove = headNode;
while (pMove){
if(pMove -> data.num == num){
printf("学号\t姓名\t班级\t地址\t电话\t\tQQ\n");
printf("%d\t%s\t%d\t%s\t%s\t%s\n", pMove->data.num, pMove->data.name, pMove->data.class, pMove->data.addr,
pMove->data.tel, pMove->data.QQ);
break;
}
pMove = pMove -> next;
}
if(pMove == NULL){
printf("学号不存在,无法查找!\n ");
return ;
}
}
//按名字查询
void searchInfoByName(struct Node* headNode,char *name){
struct Node* pMove = headNode;
while (pMove){
if(strcmp(pMove -> data.name,name) == 0){
printf("学号\t姓名\t班级\t地址\t电话\t\tQQ\n");
printf("%d\t%s\t%d\t%s\t%s\t%s\n", pMove->data.num, pMove->data.name, pMove->data.class, pMove->data.addr,
pMove->data.tel, pMove->data.QQ);
break;
}
pMove = pMove -> next;
}
if(pMove == NULL){
printf("名字不存在,无法查找!\n ");
return ;
}
}
//按班级查询
void searchInfoByClass(struct Node* headNode,int class){
struct Node* pMove = headNode;
int count = 0;
while (pMove){
if(pMove -> data.class == class){
count++;
if(count == 1)
printf("学号\t姓名\t班级\t地址\t电话\t\tQQ\n");
printf("%d\t%s\t%d\t%s\t%s\t%s\n", pMove->data.num, pMove->data.name, pMove->data.class, pMove->data.addr,
pMove->data.tel, pMove->data.QQ);
}
pMove = pMove -> next;
}
if(count == 0){
printf("班级不存在,无法查找!\n ");
return ;
}
}
//按学号修改
void alterNumNode(struct Node* headNode,int num){
struct Node* posNode = headNode -> next;
struct Node* posFrontNode = headNode;
while(posNode -> data.num != num)
{
posFrontNode = posNode;
posNode = posNode -> next;
}
if(posNode == NULL){
printf("未找该学生,无法修改!");
return;
}
else{
struct student data;
posFrontNode -> next = posNode -> next;
free(posNode);
printf("请重新输入学生的学号,姓名,班级,地址,电话,QQ:\n");
fflush(stdin);
scanf("%d %s %d %s %s %s",&data.num,data.name,&data.class,data.addr,data.tel,data.QQ);
insertNodeByHead(list,data);
printf("修改成功!");
}
}
//按姓名修改
void alterNameNode(struct Node* headNode,char* name){
struct Node* posNode = headNode -> next;
struct Node* posFrontNode = headNode;
while(strcmp(posNode -> data.name,name))
{
posFrontNode = posNode;
posNode = posNode -> next;
}
if(posNode == NULL){
printf("未找该学生,无法修改!");
return;
}
else{
struct student data;
posFrontNode -> next = posNode -> next;
free(posNode);
printf("请重新输入学生的学号,姓名,班级,地址,电话,QQ:\n");
fflush(stdin);
scanf("%d %s %d %s %s %s",&data.num,data.name,&data.class,data.addr,data.tel,data.QQ);
insertNodeByHead(list,data);
printf("修改成功!");
}
}
//统计各班级人数
void countClass(struct Node* headNode){
int i;
int count[N + 1] = {0};
struct Node* pMove = headNode;
while (pMove){
for( i = 1;i <= N; i++){
if (pMove->data.class == i ) count[i]++;
}
pMove = pMove -> next;
}
for (int i = 1;i <= N; i++) {
printf("%d班的人数为:%d\n",i,count[i]);
}
}
//统计各省份人数
void countProvince(struct Node* headNode){
char province[34][100] = {"Hebei","Shanxi","Liaoning","Jilin","Heilongjiang","Jiangsu","Zhejiang","Anhui","Fujian","Jiangxi","Shandong","Henan","Hubei","Hunan","Guangdong","Hannan","Sichuan","Guizhou","Yunnan","Shanxi","Gansu","Qinghai","Taiwan","Neimenggu","Guangxi","Xizang","Ningxia","Xinjiang","Beijiang","Tianjing","Shanghai","Chongqing","Xianggang","Aomen"};
int i;
int count[34] ={0};
struct Node* pMove = headNode;
while (pMove){
for( i = 0;i < 34; i++){
if (strcmp(pMove->data.addr,province[i]) == 0 ) count[i]++;
}
pMove = pMove -> next;
}
for (int i = 0;i < 34; i++) {
if(count[i] != 0)
printf("地址为%s的人数为%d\n",province[i],count[i]);
}
}
//按学号升序排序
void sortUp(struct Node* headNode){
struct Node* turn;
struct Node* move;
struct student temp;
for(turn = headNode -> next;turn -> next != NULL;turn = turn -> next){
for(move = headNode -> next;move -> next != NULL;move = move -> next){
if(move -> data.num > move -> next -> data.num){
temp = move -> data;
move -> data = move -> next -> data;
move -> next -> data = temp;
}
}
}
printList(list);
}
//按学号降序排序
void sortDrop(struct Node* headNode){
struct Node* turn;
struct Node* move;
struct student temp;
for(turn = headNode -> next;turn -> next != NULL;turn = turn -> next){
for(move = headNode -> next;move -> next != NULL;move = move -> next){
if(move -> data.num < move -> next -> data.num){
temp = move -> data;
move -> data = move -> next -> data;
move -> next -> data = temp;
}
}
}
printList(list);
}
//文件读操作
void readInFromFile(struct Node* headNode,char* filename){
struct student data;
FILE *fp;
fp = fopen(filename,"r");
if(fp == NULL){
printf("文件打开失败!");
}
while (fscanf(fp,"%d\t%s\t%d\t%s\t%s\t%s\n",&data.num,data.name,&data.class,data.addr,data.tel,data.QQ) != EOF){
insertNodeByHead(headNode,data);
}
fclose(fp);
}
void readInFromUser(struct User* headUser,char* filename){
struct user data;
FILE *fp;
fp = fopen(filename,"r");
if(fp == NULL){
printf("文件打开失败!");
}
while (fscanf(fp,"%s\t%s\n",data.acc,data.password) != EOF){
insertUserByHead(headUser,data);
}
fclose(fp);
}
//文件写操作
void writeInFromFile(struct Node* headNode,char* filename){
FILE *fp = fopen(filename,"w");
struct Node* pMove = headNode -> next;
while(pMove){
fprintf(fp,"%d\t%s\t%d\t%s\t%s\t%s\n",pMove->data.num,pMove->data.name,pMove->data.class,pMove->data.addr,pMove->data.tel,pMove->data.QQ);
pMove = pMove -> next;
}
fclose(fp);
}
void writeInFromUser(struct User* headUser,char* filename){
FILE *fp = fopen(filename,"w");
struct User* pMove = headUser -> next;
while(pMove){
fprintf(fp,"%s\t%s\n",pMove->data.acc,pMove->data.password);
pMove = pMove -> next;
}
fclose(fp);
}
//注册
void singUp(struct User* headUser){
char newPassword1[20];
char newPassword2[20];
char acc[20];
struct user data;
printf("请输入注册用户名:");
scanf("%s",acc);
struct User* posUser = headUser;
while(posUser)
{
if(strcmp(posUser -> data.acc,acc) == 0)
{
break;
}
posUser = posUser -> next;
}
if(posUser == NULL){
strcpy(data.acc,acc);
do {
printf("请输入密码:");
scanf("%s",newPassword1);
printf("请再次输入密码:");
scanf("%s",newPassword2);
if (strcmp(newPassword1,newPassword2) != 0)
printf("两次密码不相同,请重新输入.......\n");
}while (strcmp(newPassword1,newPassword2) != 0);
strcpy(data.password,newPassword1);
struct User* newUser = createUserNode(data);
newUser -> next = headUser -> next;
headUser -> next = newUser;
printf("注册成功!");
return;
}
else {
printf("该用户名存在,请重新注册......\n");
return;
}
}
//登录
void longIn(struct User* headUser){
int k = 3;
int i = 0;
int p = 0;
char str[20] = "\0";
struct user data;
printf("请输入用户名:");
scanf("%s",data.acc);
struct User* posUser = headUser -> next;
while(posUser)
{
if(strcmp(posUser -> data.acc,data.acc) == 0) break;
posUser = posUser -> next;
}
if(posUser == NULL) {
printf("用户不存在......");
return;
}
else {
printf("请输入密码:");
for (k = 3; k > 0;) {
int n = 0;
while ((data.password[n] = getch()) != 13) {
if (data.password[n] == 8) {
n--;
system("cls");
longinAndSingup();
printf("1\n");
printf("----------------【登录】----------------\n");
printf("请输入用户名:");
printf("%s\n", data.acc);
printf("请输入密码:");
for (int j = 0; j < n; j++) {
printf("*");
}
continue;
}
printf("*");
n++;
}
for(i = 0; i < n; i++){
str[i] = data.password[i];
}
str[i] = '\0';//转字符串
if(strcmp(posUser -> data.password,str) == 0)
p = 1;
if (p == 1) {
printf("登录成功!");
system("pause");
system("cls");
list = createList();
readInFromFile(list, "student.txt");
while (1) {
menu();
keyDown();
system("pause");
system("cls");
}
}
else {
k--;
if (k == 0) {
printf("\n您输入密码三次错误,为您自动退出....");
system("pause");
exit(0);
}
printf("\n密码错误,您还有%d次机会\n", k);
system("pause");
system("cls");
longinAndSingup();
printf("1\n");
printf("----------------【登录】----------------\n");
printf("请输入用户名:");
printf("%s\n", data.acc);
printf("请输入密码:");
p = 0;
}
}
}
}
//总界面
void longinAndSingup() {
printf("****************【学生通讯录管理系统】**************\n");
printf("****************************************************\n");
printf("*\t\t\t1.登录 *\n");
printf("*--------------------------------------------------*\n");
printf("*\t\t\t2.注册 *\n");
printf("****************************************************\n");
}
//用户交互
void key(){
int choice = 0;
scanf("%d", &choice);
switch (choice) {
case 1:
printf("----------------【登录】----------------\n");
longIn(user);
break;
case 2:
printf("----------------【注册】----------------\n");
singUp(user);
break;
default:
printf("选择错误,请重新输入......\n");
system("pause");
break;
}
writeInFromUser(user,"user.txt");
}
void keyDown(){
struct student data;
int choice = 0;
scanf("%d",&choice);
switch(choice){
case 0:
printf("正常退出。");
system("pause");
exit(0);
break;
case 1:
printf("----------------【学生通讯信息录入】----------------\n");
printf("请输入学生的学号,姓名,班级,地址,电话,QQ:\n");
fflush(stdin);
scanf("%d %s %d %s %s %s",&data.num,data.name,&data.class,data.addr,data.tel,data.QQ);
insertNodeByHead(list,data);
printf("录入成功!\n");
break;
case 2:
printf("----------------【学生通讯信息浏览】----------------\n");
printList(list);
break;
case 3:
printf("----------------【查询功能】----------------\n");
printf("\t\t1.按学号查询\n");
printf("\t\t2.按姓名查询\n");
printf("\t\t3.按班级查询\n");
keydown1();
break;
case 4:
printf("----------------【学生通讯信息删除】----------------\n");
printf("\t\t1.按学号删除\n");
printf("\t\t2.按姓名删除\n");
keydown2();
break;
case 5:
printf("----------------【学生通讯信息修改】----------------\n");
printf("\t\t1.按学号查找并修改\n");
printf("\t\t2.按姓名查找并修改\n");
keydown3();
break;
case 6:
printf("----------------【学生通讯信息排序】----------------\n");
printf("\t\t1.按学号升序排序\n");
printf("\t\t2.按学号降序排序\n");
keydown4();
break;
case 7:
printf("----------------【学生通讯信息统计】----------------\n");
printf("\t\t1.统计各班人数\n");
printf("\t\t2.统计各省份人数\n");
keydown5();
break;
default:
printf("选择错误,请重新输入......\n");
system("pause");
}
writeInFromFile(list,"student.txt");
}
void keydown1(){
int choice = 0;
scanf("%d",&choice);
struct student data;
switch(choice){
case 1:
printf("----------------【按学号查询】----------------\n");
printf("请输入学号:");
scanf("%d",&data.num);
searchInfoByNum(list,data.num);
break;
case 2:
printf("----------------【按姓名查询】----------------\n");
printf("请输入姓名:");
scanf("%s",data.name);
searchInfoByName(list,data.name);
break;
case 3:
printf("----------------【按班级查询】----------------\n");
printf("请输入班级:");
scanf("%d",&data.class);
searchInfoByClass(list,data.class);
break;
default:
printf("选择错误,请重新输入......\n");
system("pause");
break;
}
}
void keydown2(){
struct student data;
int choice = 0;
scanf("%d",&choice);
switch(choice){
case 1:
printf("----------------【按学号删除】----------------\n");
printf("请输入删除学生的学号:\n");
scanf("%d",&data.num);
deleteNumNode(list,data.num);
break;
case 2:
printf("----------------【按姓名删除】----------------\n");
printf("请输入删除学生的姓名:\n");
scanf("%s",data.name);
deleteNameNode(list,data.name);
break;
default:
printf("选择错误,请重新输入......\n");
system("pause");
break;
}
}
void keydown3() {
struct student data;
int choice = 0;
scanf("%d", &choice);
switch (choice) {
case 1:
printf("----------------【按学号查找并修改】----------------\n");
printf("请输入需要修改学生的学号:\n");
scanf("%d", &data.num);
alterNumNode(list, data.num);
break;
case 2:
printf("----------------【按姓名查找并修改】----------------\n");
printf("请输入需要修改学生的姓名:\n");
scanf("%s", data.name);
alterNameNode(list,data.name);
break;
default:
printf("选择错误,请重新输入......\n");
system("pause");
break;
}
}
void keydown4(){
int choice = 0;
scanf("%d", &choice);
switch (choice) {
case 1:
printf("----------------【按学号升序排序】----------------\n");
sortUp(list);
break;
case 2:
printf("----------------【按学号降序排序】----------------\n");
sortDrop(list);
break;
default:
printf("选择错误,请重新输入......\n");
system("pause");
break;
}
}
void keydown5(){
int choice = 0;
scanf("%d", &choice);
switch (choice) {
case 1:
printf("----------------【统计各班人数】----------------\n");
countClass(list);
break;
case 2:
printf("----------------【统计各省份人数】----------------\n");
countProvince(list);
break;
default:
printf("选择错误,请重新输入......\n");
system("pause");
break;
}
}
int main()
{
user = createUser();
readInFromUser(user,"user.txt");
while(1)
{
longinAndSingup();
key();
system("pause");
system("cls");
}
}