写c语言管理系统过程中遇到的问题 及其解决办法

由于写的是学生成绩管理系统,需要用结构体来存储学生的各项成绩,当然还有学号 班级 姓名

#define LEN 20
typedef struct student {
	char name[LEN];
	char num[10];
	char theClassName[LEN];
	
	int grade1;
	int grade2;
	int grade3;
	
	char accountNumber[LEN];//学生账好
	char passWord[LEN];	//账户密码
	
	struct student* next;
}STU;

三个界面:

//打印界面 。
//学生
void printSTUScreen() {
	printf("\t\t\t\t\t---------------------------------\n");
	printf("\t\t\t\t\t|-------学生成绩管理系统--------|\n");	
	printf("\t\t\t\t\t|-------请输入:0~5之间的数字 --|\n");
	
	printf("\t\t\t\t\t|-------1.查询我的成绩----------|\n");
	printf("\t\t\t\t\t|-------2.查询本班成绩----------|\n");
	printf("\t\t\t\t\t|-------3.成绩分析--------------|\n");
	printf("\t\t\t\t\t|-------4.我要申诉--------------|\n");
	printf("\t\t\t\t\t|-------5.返回------------------|\n");
	printf("\t\t\t\t\t|-------0.退出系统--------------|\n");
	printf("\t\t\t\t\t---------------------------------\n");
	
	
	
} 
//老师
void printTEScreen() {
	printf("\t\t\t\t\t------------------------------------------\n");
	printf("\t\t\t\t\t|-------学生成绩管理系统-----------------|\n");	
	printf("\t\t\t\t\t|-------请输入:0~9之间的数字 -----------|\n");
	
	printf("\t\t\t\t\t|-------1.增加新的学生信息---------------|\n");
	printf("\t\t\t\t\t|-------2.删除学生信息-------------------|\n");
	printf("\t\t\t\t\t|-------3.修改学生信息-------------------|\n");
	printf("\t\t\t\t\t|-------4.查询学生信息-------------------|\n");
	printf("\t\t\t\t\t|-------5.输出本班成绩-------------------|\n");
	printf("\t\t\t\t\t|-------6.下载到文件中-------------------|\n");
	printf("\t\t\t\t\t|-------7.成绩分析-----------------------|\n");
	printf("\t\t\t\t\t|-------8.提醒管理员进行成绩的更新-------|\n");
	printf("\t\t\t\t\t|-------9.返回上一层---------------------|\n");	
	printf("\t\t\t\t\t|-------0.退出系统-----------------------|\n");
	printf("\t\t\t\t\t------------------------------------------\n");
	
	
}
//管理员
void printADScreen() {
	printf("\t\t\t\t\t---------------------------------------\n");
	printf("\t\t\t\t\t|-------学生成绩管理系统--------------|\n");	
	printf("\t\t\t\t\t|-------请输入:0~a之间的数字 --------|\n");
	
	printf("\t\t\t\t\t|-------1.查看代办事项----------------|\n");
	printf("\t\t\t\t\t|-------2.进入教师端进行信息修改------|\n");
	printf("\t\t\t\t\t|-------3.增加账号及密码--------------|\n");
	printf("\t\t\t\t\t|-------4.删除账号及密码--------------|\n");
	printf("\t\t\t\t\t|-------5.修改账号及密码--------------|\n");
	printf("\t\t\t\t\t|-------6.查找账号及密码--------------|\n");
	printf("\t\t\t\t\t|-------7.录入所有账号及密码----------|\n");
	printf("\t\t\t\t\t|-------8.输出所有账号级密码----------|\n");
	printf("\t\t\t\t\t|-------9.手动重新录入学生信息--------|\n");
	printf("\t\t\t\t\t|-------a.返回上一层------------------|\n");
	printf("\t\t\t\t\t|-------0.退出系统--------------------|\n");
	printf("\t\t\t\t\t---------------------------------------\n");
}

所用到的文件的基本操作

fopen:

打开文件
FILE* fopen(“文件路径名称”,“模式字符串”);
模式字符串:
r:以读模式打开文件,若文件不存在会报错。
w:以写模式打开文件,若文件已存在则文件原有内容会丢失,若文件不存在,则创建一个新的文件。
a:以写模式打卡文件,不会使原来的数据丢失,会以追加的方式,继续向文件写数据。

其他的模式不常用,这次写系统我也没有用到,略过。

fclose:

关闭文件
int fclose(FILE* fp);
成功关闭时返回值为0
若未能成功关闭,则返回EOF(-1)

fprintf:

与printf各种方式较为类似,fprintf的第一个参数是文件指针,后面的是格式化列表(与字符串(也可能没有))。
可以用fprintf向文件中输入数据。

feof:

feof()是检测流上的文件结束符的函数,如果文件结束,则返回非0值,否则返回0

账户登录注册问题及其方案

管理系统要求是有三个界面,应对不同人群:学生,教师,管理员
这里是另外的两种结构体:

//教师账户 。
typedef struct teachers {
	char accountNumber[LEN];
	char passWord[LEN];	
	struct teachers* next;
}TE;
//有管理权限的账号 。 
typedef struct administrators {
	char accountNumber[LEN];
	char passWord[LEN];	
	struct administrators* next;
}AD;

我的思路是用文件来记录账户和密码,程序开始先调用函数把文件中的账户和密码用链表来存储,然后在登录验证时把链表遍历,当找到符合的节点时便登陆成功,遍历完没有找到即登陆失败。

此处再附上登录验证的函数和文件信息录入链表的函数:

//这里是main的一部分代码:
char sn;
		printf("a.登录        b.注册\n"); 
		scanf("%c",&sn);
		//学生登录 
		if(sn == 'a') {
			start = logOn1(STUlist);
		}
		//学生账号注册 
		if(sn == 'b') {
			char sacc[LEN],spas[LEN];
			printf("注册:\n");
	
			printf("请输入账号:\n");
			scanf("%s",&sacc);
			getchar();
			printf("请输入密码:\n");
			scanf("%s",&spas);
			getchar();
			logIn1(sacc, spas);
		}

登录

//登录 。 
int logOn1(STU* list) {
	char acc1[LEN],pas1[LEN];
	printf("登录:\n");
	
	printf("请输入学生账号:\n");
	scanf("%s",&acc1);
	
	printf("请输入密码:\n");
	scanf("%s",&pas1);
	
	STU* quiry1 = list;
	while(quiry1) {
		if(strcmp((quiry1 -> accountNumber), acc1) == 0)
		{
			if(strcmp((quiry1 -> passWord), pas1) == 0) {
				printf("登录成功!\n");
				return 1;
			}
		}
		quiry1 = quiry1 -> next; 
	}
	printf("输入有误\n");
	return 0;
}

遍历链表中的账号密码来判断是否输入了正确的账号密码。

注册

把输入的信息录入文件中保存。

void logIn1(char* accountNumber, char* passWord) {
	FILE* fp1 = fopen("C:\\Users\\zds\\Desktop\\.vs\\账户信息1.txt", "a");
	
	fprintf(fp1, "%s ", accountNumber);//这里%s后应有空格 
	fprintf(fp1, "%s\n", passWord);

	int ret = fclose(fp1);
	if(ret == 0) {
		printf("注册完成。\n");
	} else {
		printf("文件关闭失败,请重新启动。\n");
		exit(1);
	}

} 

另外的两种结构体对应的登录、注册函数:

void logIn2(char* accountNumber, char* passWord) {
	FILE* fp2 = fopen("C:\\Users\\zds\\Desktop\\.vs\\账户信息2.txt", "a");
	
	fprintf(fp2, "%s ", accountNumber);//这里%s后应有空格 
	fprintf(fp2, "%s\n", passWord);

	int ret = fclose(fp2);
	if(ret == 0) {
		printf("注册完成。\n");
	} else {
		printf("文件关闭失败,请重新启动。\n");
		exit(1);
	}

} 
void logIn3(char* accountNumber, char* passWord) {
	FILE* fp3 = fopen("C:\\Users\\zds\\Desktop\\.vs\\账户信息3.txt", "a");
	
	fprintf(fp3, "%s ", accountNumber);//这里%s后应有空格 
	fprintf(fp3, "%s\n", passWord);

	int ret = fclose(fp3);
	if(ret == 0) {
		printf("注册完成。\n");
	} else {
		printf("文件关闭失败,请重新启动。\n");
		exit(1);
	}

} 

登录

//教师登录 。 
int logOn2(TE* list) {
	char acc2[LEN],pas2[LEN];
	printf("登录:\n");
	
	printf("请输入教师账号:\n");
	scanf("%s",&acc2);
	
	printf("请输入教师密码:\n");
	scanf("%s",&pas2);
	
	TE* quiry2 = list;
	while(quiry2) {
		if(strcmp((quiry2 -> accountNumber), acc2) == 0)
		{
			if(strcmp((quiry2 -> passWord), pas2) == 0) {
				printf("登录成功!\n");
				return 1;
			}
		}
		quiry2 = quiry2 -> next; 
	}
	printf("输入有误\n");
	return 0;
}
//管理员登录 。 
int logOn3(AD* list) {
	char acc3[LEN],pas3[LEN];
	printf("登录:\n");
	
	printf("请输入管理员账号:\n");
	scanf("%s",&acc3);
	
	printf("请输入密码:\n");
	
	scanf("%s",&pas3);
	
	AD* quiry3 = list;
	while(quiry3) {
		if(strcmp((quiry3 -> accountNumber), acc3) == 0)
		{
			if(strcmp((quiry3 -> passWord), pas3) == 0) {
				printf("登录成功!\n");
				return 1;
			}
		}
		quiry3 = quiry3 -> next; 
	}
	printf("输入有误\n");
	return 0;
}


增删改查:

增:

//增加账号及密码
void addAccount1(STU* tail) {
	STU* node = (STU*)malloc(sizeof(STU));
	node->next=NULL;
	printf("输入账号");
	scanf("%s", &node->accountNumber);
	printf("输入密码");
	scanf("%s",&node->passWord);
	tail -> next = node;
	tail = tail -> next;
	
}

这里是用的尾插法来增加节点。
删:

// 删除账号 
STU* delAccount1(STU* head){
	printf("请输入需删除账号:\n");
	char delNum[LEN];
	scanf("%s", &delNum);
	STU* phead = head;
	if(strcmp(phead->accountNumber,delNum)==0){
		return head -> next;
	}
	while(phead&&phead->next){
		if(strcmp(phead->next->num,delNum)==0){
			phead -> next = phead -> next -> next;
		}else {
			phead = phead -> next;
		}
		
	}
	return head;
}

改:

STU* modAccount1(STU* head) {
	printf("请输入需修改信息的帐号:\n");
	char delNum[LEN];
	scanf("%s", &delNum);
	STU* phead = head;
	while(phead) {
		if(strcmp(phead->accountNumber, delNum)==0){
			printf("输入账号\n");
			scanf("%s",&phead->accountNumber);
			printf("输入密码\n");
			scanf("%s",&phead->passWord); 
			break;
		}
		else {
			phead = phead->next;
		}
	}
	return head;
}

利用结构体内部的accountNumber来判断节点,也就是说用账号来查找要修改的学生节点。这里使用strcmp()函数来进行判断。当找到节点并修改完成后,直接break跳出,减少无用的循环。
查:

//教师端查找学生信息
void queryGrade(STU* head){
	printf("请输入需修改信息的学生的学号:\n");
	char delNum[LEN];
	scanf("%s", &delNum);
	STU* phead = head;
	while(phead){
		if(strcmp(phead->next->num,delNum)==0){
			printf("姓名:    学号:    班级:     成绩1: 成绩2: 成绩3:\n");
			printf("%6s   %6s   %6s        %3d    %3d    %3d\n", phead->name, phead->num, phead->theClassName, phead->grade1, phead->grade2, phead->grade3);
		} else {
			phead = phead -> next;
		}
	}
	return ;
}

遍历链表来查找学生信息

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值