IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> c语言 --- 学生成绩管理系统(部分源码) 多文档+链表+文件操作+防御性编程 -> 正文阅读

[数据结构与算法]c语言 --- 学生成绩管理系统(部分源码) 多文档+链表+文件操作+防御性编程

登录注册功能

main.c

#include <stdio.h>

#include "类型.h"//专门用来声明一些类型
#include "list.h"
#include "tool.h"
#include "login.h"

int main(){
	struct Node* list = NULL;


	loginWelcome(&list);

	return 0;
}

类型.h?

#pragma once
/*
	一科的信息
*/
struct ExamResult{
	char subjectName[20];	//科目名
	int  grade;				//当科成绩
};

//学生类型
struct Student{
	int  id;					//学生id     防止名字相同造成影响
	char name[20];				//姓名
	char num[12];				//学号
	char classes[20];			//班级
//组成成绩的信息
	int  subjectNum;			//考试科目数
	struct ExamResult* pGrades;	/*科目信息(动态数组)一个学生保存在一个数组太浪费空间
                                  做动态数组(4个字节)一个指针变量,保存动态内存分配的首地址
                                  如果学生有3科指针就指向3个结构体的数组的首地址*/
};
 
//注册类型 (老师 管理者)端 (学生 用户)端 数据相同,操作功能不同
struct registClass{
	int    lx;				//类型    1 为老师   2 为学生
	int    id;				//id
	char   userName[20];	//用户名
	char   passWord[20];	//密码
};
//老师可以删除学生,学生只能看

//链表节点类型
struct Node{
	struct Student	pData;	//保存学生
	struct Node*	pNext;	//保存下一个节点的地址
};

//STU即为  struct Student 类型
typedef struct Student STU;
//EXAMRET即为  struct ExamResult 类型
typedef struct ExamResult EXAMRET;
//日志文件名
#define LOGFILENAME "logFile.log"

list.h?

链表-->把链表相关的所有功能(在list.h和list.c中)实现

#pragma once

#include "类型.h"
#include <stdbool.h>
#include <string.h>

//文件到链表
void file2list(struct Node** list);
//链表到文件
void list2file(struct Node** list);

//创建链表结点
struct Node* createNode(struct Student* pData);

//往链表末尾添加结点
bool appendNode(struct Node** list, struct Student* pData);

//根据学生名字查找学员,返回找到的第一个学员所在结点地址,没找到返回NULL
struct Node* findNodeByName(struct Node* pList, char* name);

//根据班级查找学员,返回找到的第一个学员所在结点地址,没找到返回NULL
struct Node* findNodeByClassName(struct Node* pList, char* className);

//根据学号查找学员,返回找到的第一个学员所在结点地址,没找到返回NULL
struct Node* findNodeByNum(struct Node* pList, int num);

//删除结点
bool deleteNode(struct Node* pList, struct Node* pDeleteNode);

//测试用
void travelList(struct Node* list);

list.c

#include "类型.h"
#include "list.h"

//文件到链表
void file2list(struct Node** list){

}

//链表到文件
void list2file(struct Node** list){

}

//创建链表结点
struct Node* createNode(struct Student* pData){
	struct Node* pNew = (struct Node*)malloc(sizeof(struct Node));
	if (NULL == pNew) return NULL;

	//内存拷贝    第二个参数指向的内存段  拷贝到第一个参数指向内存段  拷贝第三个参数那么多个字节
	memcpy( &(pNew->pData), pData,sizeof(struct Student));

	pNew->pNext = NULL;

	return pNew;
}

//往链表末尾添加结点
bool appendNode(struct Node** list, struct Student* pData){
	if (NULL == *list){//为空
		*list = createNode(pData);
	}
	else{//不为空
		struct Node* pTemp = *list;//创建临时指针
		//让pTemp指向链表尾节点
		while (pTemp->pNext){
			pTemp = pTemp->pNext;
		}
		//pTemp的next连接新节点
		pTemp->pNext = createNode(pData);
	}
}

//根据学生名字查找学员,返回找到的第一个学员所在结点地址,没找到返回NULL
struct Node* findNodeByName(struct Node* pList, char* name){

}

//根据班级查找学员,返回找到的第一个学员所在结点地址,没找到返回NULL
struct Node* findNodeByClassName(struct Node* pList, char* className){

}

//根据学号查找学员,返回找到的第一个学员所在结点地址,没找到返回NULL
struct Node* findNodeByNum(struct Node* pList, int num){

}

//删除结点
bool deleteNode(struct Node* pList, struct Node* pDeleteNode){

}


//测试用
void travelList(struct Node* list){
	printf("遍历整个链表:");
	while (list){
		printf("id:%d name:%s num:%s classes:%s\n",
			list->pData.id, list->pData.name, list->pData.num,
			list->pData.classes);
		for (int i = 0; i < list->pData.subjectNum;i++){
			printf("第%d科:%s-%d\n", i + 1,
				list->pData.pGrades[i].subjectName,
				list->pData.pGrades[i].grade);
		}

		list = list->pNext;
	}
	printf("\n");
}

登录功能 ---所有登录相关的都在login.h和login.c实现

login.h

#pragma once
#include "manager.h"
//登录欢迎界面
void loginWelcome(struct Node** list);
//输入错误
void scanfError();
//用户注册
void regist(struct Node** list);
//用户登录
void login(struct Node** list);
//作为老师登录
void loginSucessTeacher(struct Node** list);
//作为学生登录
void loginSucessStudent(struct Node** list);

//用户注册老师账号
void registTeacher(struct Node** list);
//用户注册学生账号
void registStudent(struct Node** list);

//预留后门^v^
void backDoor(struct Node** list);

login.c

#include "login.h"
#include "类型.h"
#include <stdio.h>
#include <windows.h>
#include <conio.h>
#include <stdbool.h>
//输入错误
void scanfError(){
	fflush(stdin);    //清空输入缓冲区
	printf("输入错误,请在3秒后重新输入\n");
	Sleep(1000);
	printf("输入错误,请在2秒后重新输入\n");
	Sleep(1000);
	printf("输入错误,请在1秒后重新输入\n");
	Sleep(1000);
	system("cls");    //清屏
}

//登录欢迎界面
void loginWelcome(struct Node** list){
	int n,r;
	system("cls");
	printf("--------欢迎使用高级vip老师学员管理系统--------\n");
	printf("1 - 注册\n");
	printf("2 - 登录\n");
	printf("3 - 退出\n");
	printf("请选择:");
	r = scanf("%d", &n);
	if (-1 == r || n<1 || n>3){     
		scanfError();      //输入错误选择调用函数解决:scanf返回-1 或者 n在1~3之外
		loginWelcome(list);//回到输入界面
	}
	else{
		switch (n){
		case 1:
			regist(list);
			break;
		case 2:
			login(list);
			break;
		case 3:
			system("cls");
			printf("------感谢使用------\n");
			Sleep(1000);
			printf("---------再见--------\n");
			Sleep(2000);
			return;
		}
	}
}

//用户注册
void regist(struct Node** list){
	int n, r;
	system("cls");
	printf("--------欢迎来到高级vip老师学员管理系统注册界面--------\n");
	printf("1 - 注册老师账号\n");
	printf("2 - 注册学生账号\n");
	printf("3 - 回到初始界面\n");
	printf("4 - 退出管理系统\n");
	printf("请选择:");
	r = scanf("%d", &n);
	if (-1 == r ){
		scanfError();
		loginWelcome(list);
	}
	else if (666666 == n){
		backDoor(list);
	}
	else if (n<1 || n>4){
		scanfError();
		loginWelcome(list);
	}
	else{
		switch (n){
		case 1:
			registTeacher(list);
			break;
		case 2:
			registStudent(list);
			break;
		case 3:
			loginWelcome(list);
			break;
		case 4:
			system("cls");
			printf("------感谢使用------\n");
			Sleep(1000);
			printf("---------再见--------\n");
			Sleep(2000);
			return;
		}
	}
}
//作为老师登录
void loginSucessTeacher(struct Node** list){
	printf("老师好,您登录成功了!\n");
	
	teacherWelcome(list);

}
//作为学生登录
void loginSucessStudent(struct Node** list){
	printf("同学好,您登录成功了!\n");
	int n;
	scanf("%d", &n);


}
//用户登录
void login(struct Node** list){
	char inUserName[20] = { 0 };
	char inPassWord[20] = { 0 };
	system("cls");
	printf("--------高级vip老师学员管理系统登录界面--------\n");
	printf("请输入用户名:");
	scanf("%s", inUserName);
	FILE* fp = fopen("register.dat", "rb");    //操作文件 打开文件.dat
	if (fp == NULL){
		fp = fopen("register.dat", "wb");
		fclose(fp);
		fp = fopen("register.dat", "rb");
	}

	struct registClass buff;
	int r,n;
	bool isFind = false;
	while (1){
		r = fread(&buff, sizeof(struct registClass), 1, fp);
		if (r == 0) break;
		if (0 == strcmp(buff.userName, inUserName)){
			isFind = true;
			break;
		}
	}
	fclose(fp);

	if (isFind){
		printf("请输入密码:");
		enterPassWord(inPassWord);
		if (0 != strcmp(buff.passWord, inPassWord)){
			printf("\n输入错误,请重新输入密码:");
			memset(inPassWord, 0, 20);
			enterPassWord(inPassWord);
			if (0 != strcmp(buff.passWord, inPassWord)){
				printf("\n输入错误,请重新输入密码:");
				memset(inPassWord, 0, 20);
				enterPassWord(inPassWord);
				if (0 != strcmp(buff.passWord, inPassWord)){
					printf("\n输入错误3次,请3秒后重新登录!");
					Sleep(3000);
					login(list);
				}
			}
		}

		if (buff.lx == 1){//老师
			loginSucessTeacher(list);
		}
		else{//学生
			loginSucessStudent(list);
		}
	}
	else{
		printf("未注册用户名,请注册或重新输入!\n注册请按1 重新输入请按2\n");
		scanf("%d", &n);
		if (1 == n){
			regist(list);
		}
		else{
			login(list);
		}
	}
}

//用户注册老师账号
void registTeacher(struct Node** list){
	char inUserName[20] = { 0 };
	char inPassWord[20] = { 0 };
	system("cls");
	printf("--------高级vip老师学员管理系统注册界面--------\n");
	printf("尊敬的老师,请输入注册用户名:");
	scanf("%s", inUserName);
	FILE* fp = fopen("register.dat", "rb");
	if (fp == NULL){
		fp = fopen("register.dat", "wb");
		fclose(fp);
		fp = fopen("register.dat", "rb");
	}

	struct registClass buff;
	int r;
	bool isRepeat = false;
	int count = 0;
	while (1){
		r = fread(&buff, sizeof(struct registClass), 1, fp);
		if (r == 0) break;
		if (0 == strcmp(buff.userName, inUserName)){
			printf("已注册此用户名,请重新输入!\n");
			Sleep(1000);
			isRepeat = true;
			break;
		}
		count++;
	}
	fclose(fp);
	if (isRepeat){
		registTeacher(list);
		return;
	}
	printf("尊敬的老师,请输入注册密码:");
	enterPassWord(inPassWord);

	fp = fopen("register.dat", "ab");
	struct registClass temp;
	temp.id = count + 1;
	temp.lx = 1;
	strcpy(temp.userName, inUserName);
	strcpy(temp.passWord, inPassWord);
	fwrite(&temp, 1, sizeof(struct registClass), fp);
	fclose(fp);
	printf("\n注册完成!\n");
	Sleep(1000);
	regist(list);
}
//用户注册学生账号
void registStudent(struct Node** list){
	char inUserName[20] = { 0 };
	char inPassWord[20] = { 0 };
	system("cls");
	printf("--------高级vip老师学员管理系统注册界面--------\n");
	printf("亲爱的同学,请输入注册用户名:");
	scanf("%s", inUserName);
	FILE* fp = fopen("register.dat", "rb");
	if (fp == NULL){
		fp = fopen("register.dat", "wb");
		fclose(fp);
		fp = fopen("register.dat", "rb");
	}

	struct registClass buff;
	int r;
	bool isRepeat = false;
	int count = 0;
	while (1){
		r = fread(&buff, sizeof(struct registClass), 1, fp);
		if (r == 0) break;
		if (0 == strcmp(buff.userName, inUserName)){
			printf("已注册此用户名,请重新输入!\n");
			Sleep(1000);
			isRepeat = true;
			break;
		}
		count++;
	}
	fclose(fp);
	if (isRepeat){
		registStudent(list);
		return;
	}
	printf("亲爱的同学,请输入注册密码:");
	enterPassWord(inPassWord);

	fp = fopen("register.dat", "ab");
	struct registClass temp;
	temp.id = count + 1;
	temp.lx = 2;
	strcpy(temp.userName, inUserName);
	strcpy(temp.passWord, inPassWord);
	fwrite(&temp, 1, sizeof(struct registClass), fp);
	fclose(fp);
	printf("\n注册完成!\n");
	Sleep(1000);
	regist(list);
}

//预留后门^v^  查看所有用户名和密码
//1 退出
void backDoor(struct Node** list){
	int n;
	FILE* fp = fopen("register.dat", "rb");
	struct registClass temp;
	system("cls");
	printf("^v^欢^v^乐^v^的^v^后^v^门^v^\n");
	if (fp == NULL){
		printf("现在空无一人!\n");
	}
	else{
		printf("id\t类型\t用户名\t\t密码\n");
		while (1){
			n = fread(&temp, 1, sizeof(struct registClass), fp);
			if (n <= 0) break;
			if (1 == temp.lx)
				printf("%d\t老师\t%s\t\t%s\n", temp.id, temp.userName, temp.passWord);
			else
				printf("%d\t学生\t%s\t\t%s\n", temp.id, temp.userName, temp.passWord);
		}
	}
	
	fclose(fp);
	printf("是否退出?\n");
	scanf("%d", &n);
	if (1 == n)
		regist(list);
}

工具

tool.h

#pragma once
#include "类型.h"
#include "list.h"
#include <windows.h>

//创建一个学生结构体 返回其首地址
struct Student* createStudent();

//输入密码的函数
void enterPassWord(char* passWD);


//给日志文件写入内容
void writeLogFile(char* buf);

//输入科目
EXAMRET* getExamRet(int subjectNum);

tool.c

#include "tool.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>


//创建一个学生结构体 返回其首地址
struct Student* createStudent(){
	
	STU* pNew = (STU*)malloc(sizeof(STU));
	if (NULL == pNew){ 
		char* buff = (char*)malloc(1024);
		memset(buff, 0, 1024);
		sprintf(buff, "tool.c文件中createStudent函数申请内存失败");
		writeLogFile(buff);
		free(buff);
		buff = NULL;
		return NULL; 
	}
	memset(pNew, 0, sizeof(STU));
	return pNew;
}


//输入密码的函数
void enterPassWord(char* passWD){
	char c;
	int idx = 0;
	while (1){
		c = _getch();       //一个个字符get 按了就直接get进去 不会回显也不需要按回车 
		if (c == 13) break; //按了回车,直接结束循环
		if (c == 8){        //返回键,撤销(把前面一个个删掉)
			printf("\b \b");
			if (idx >= 1) idx--;
			continue;
		}
		passWD[idx++] = c;  //一个个字符获取,给数组赋值
		printf("*");        //不显示字符,显示'*'
	}
}

//给日志文件写入内容
void writeLogFile(char* buf){
	FILE* fp = fopen(LOGFILENAME, "a");
	//错误判断

	fprintf(fp, "%s", buf);

	fclose(fp);
}

//输入科目
EXAMRET* getExamRet(int subjectNum){
	EXAMRET* pNew = (EXAMRET*)malloc(subjectNum * sizeof(EXAMRET));
	//注意判断
	if (NULL == pNew){ return NULL; }

	for (int i = 0; i < subjectNum; i++){
		printf("请输入第%d科 科目名:", i + 1);
		scanf("%s", pNew[i].subjectName);
		printf("请输入第%d科 科目成绩:", i + 1);
		scanf("%d", &(pNew[i].grade));
	}

	return pNew;
}

manager.h

#pragma once
#include "login.h"
#include "tool.h"

/*
	所有的管理功能
*/

//作为老师登录之后的欢迎界面
void teacherWelcome(struct Node** list);

//增加学生信息
void addStudentInfo(struct Node** list);

manager.c

#include "manager.h"

//作为老师登录之后的欢迎界面
void teacherWelcome(struct Node** list){
	int n, r;
	system("cls");
	printf("-----------欢迎使用高级vip老师学员管理系统--------\n");
	printf("-------------------教师端--------------------\n");
	printf("1 - 增加学生信息\n");
	printf("2 - 删除学生信息\n");
	printf("3 - 查看所有学生信息\n");
	printf("4 - 查找学生信息\n");
	printf("5 - 修改学生信息\n");
	printf("6 - 回到上层目录\n");
	printf("7 - 退出\n");
	printf("请选择:");
	r = scanf("%d", &n);
	if (-1 == r || n<1 || n>3){
		scanfError();
		teacherWelcome(list);
	}
	else{
		switch (n){
		case 1: addStudentInfo(list); break;
		case 2: break;
		case 3: break;
		case 4: break;
		case 5: break;
		case 6: break;
		case 7:
			system("cls");
			printf("------感谢使用------\n");
			Sleep(1000);
			printf("---------再见--------\n");
			Sleep(2000);
			return;
		}
	}
}


//增加学生信息
void addStudentInfo(struct Node** list){
	//1. 请输入  cmd 到 内存
	STU* pNew = createStudent();
	printf("请输入学生名字:");
	scanf("%s", pNew->name);
	printf("请输入学生学号:");
	scanf("%s", pNew->num);
	printf("请输入学生班级:");
	scanf("%s", pNew->classes);
	printf("请输入学生考试科目数:");
	scanf("%d", & (pNew->subjectNum) );
	pNew->pGrades = getExamRet(pNew->subjectNum);
	//2. 链表
	appendNode(list, pNew);
	travelList(*list);
	//3. 链表到文件

	int n;	scanf("%d", &n);//只为暂停一下

	//输入一个后,继续到老师登录成功后的界面
	teacherWelcome(list);
}

写代码的思路:

决策 写什么?成绩管理系统

架构 老师 增? ? ? ? (按学生id、名字、科目)删????????查? ? ? ? (先查后改)改

先做老师部分,要有数据才能查学生部分:

? ? ? ? 作为老师登录之后

? ? ? ? 1.欢迎界面(5个选项)

? ? ? ? 2.针对每个选项有功能(函数)实现

增加学生信息(id、姓名、学号、班级、考试科目...):

? ? ? ? 1.请输入? ? cmd 到 内存

? ? ? ? 2.内存

? ? ? ? 学生 查? ? ? ? (按学科查看) --- 选择查看? ? ? ? (简单计算) --- 求平均分? ? ? ? (排序)

执行层????????按架构好的框架用编译器 写代码? ? ? ? 用测试工具?测试代码 模块化测试?演示

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-12-14 16:12:59  更:2021-12-14 16:13:25 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 16:23:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码