C語言實現(xiàn)學生管理系統(tǒng)總結(jié)
本文實例為大家分享了C語言實現(xiàn)學生管理系統(tǒng)的具體代碼,供大家參考,具體內(nèi)容如下
前言
本周完成了學生管理系統(tǒng),在完成的過程中遇見了許多問題,今天來總結(jié)上周寫管理系統(tǒng)一些比較困難的模塊。
登陸界面
在寫學生管理系統(tǒng)時,我首先寫的是登陸界面,學生管理系統(tǒng)有三個身份的id,分別是管理員,老師,與學生。我的想法是輸入賬號,系統(tǒng)可以自動識別賬戶的身份,所以我的結(jié)構(gòu)體設(shè)計如下:
struct personid { ? ? ? // 賬戶數(shù)據(jù)結(jié)構(gòu) ? ? char id[20]; ? ? char cypher1[20]; ? ? char quanxian[20]; ? ? char classnum[20]; ? ? struct personid *next; };
用字符串存儲賬號,密碼,權(quán)限,以及學號或者班級。
在登陸前首先應(yīng)該用鏈表提取文件中的賬號。代碼如下:
struct personid *Create(char name[]) { ?//從文件中讀取賬戶; ? ? FILE *fp = fopen(name, "r"); ? ? if (fp == NULL) { ? ? ? ? ? ? printf("不存在文件%s\n", name); ? ? ? ? ? ? exit(1); ? ? } ? ? struct personid *head = (struct personid*)malloc(sizeof(struct personid)); ? ? head->next = NULL; ? ? while (!(feof(fp))) { ? ? ? ? struct personid *p = (struct personid*)malloc(sizeof(struct personid)); ? ? ? ? fscanf(fp, "%s %s %s %s\n", p->id, p->cypher1, p->quanxian, p->classnum); ? ? ? ? p->next = head->next; ? ? ? ? head->next = p; ? ? } ? ? fclose(fp); ? ? return ?head; }
下面是登陸界面的代碼:
void menu() { ? ? //初始界面 ? ? printf("--------[歡迎進入學生管理系統(tǒng)]--------\n"); ? ? printf("1.登錄賬戶\n"); ? ? printf("2.注冊賬戶\n"); ? ? printf("3.修改密碼\n"); ? ? printf("4.找回密碼\n"); ? ? printf("0.退出系統(tǒng)\n"); ? ? printf("----------------------------------\n"); ? ? setbuf(stdin, NULL); ? ? keydown(); } void keydown() { ? ? char choice[50]; ? ? scanf("%s", choice); ? ? setbuf(stdin, NULL); ? ? if (choice[1] == '\0') { ? ? ? ? switch (choice[0]) { ? ? ? ? ? ? case '0': ? ? ? ? ? ? ? ? exit(0); ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? case '1': ? ? ? ? ? ? ? ? denglu(); ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? case '2': ? ? ? ? ? ? ? ? zhuce(); ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? case '3': ? ? ? ? ? ? ? ? xiugai(); ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? case '4': ? ? ? ? ? ? ? ? zhaohui(); ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? default: ? ? ? ? ? ? ? ? printf("無效輸入\n"); ? ? ? ? ? ? ? ? menu(); ? ? ? ? ? ? ? ? break; ? ? ? ? } ? ? } else { ? ? ? ? printf("無效輸入\n"); ? ? ? ? menu(); ? ? } ? ?? }
在寫系統(tǒng)時一定要注意程序的穩(wěn)定性,我的程序是通過不斷輸入來進行操作的,一開始我在寫代碼時,利用的是getchar函數(shù)來進行輸入,造成了輸入多個字符之后程序就會崩掉的問題,在后來修改時,將所有的getchar函數(shù)換成的scanf來輸入,這樣可以保證程序的穩(wěn)定性,在進行判斷時只需判斷輸入的是否是一個字符且有這個操作即可。
在macOS系統(tǒng)下可以利用setbuf(stdin, NULL) 來清除緩沖區(qū)。
注冊操作
如果新用戶進入程序,那么首先進行的操作就是注冊操作,我在最開始寫注冊操作時,是讓 用戶自己輸入自己的身份 ,這樣的寫法是很失敗的,如果學生進行操作,也可以注冊管理員,是很不嚴謹?shù)模?br />后來在修改時,利用了不同的邀請碼注冊不同的身份,用戶無需輸入身份,學生只需輸入自己的學號,老師則需要選擇自己對應(yīng)的班級。
代碼如下:
void zhuce() { ? ? printf("請輸入邀請碼:\n"); ? ? int yaoqingma1 = 111; ? ? int yaoqingma2 = 222; ? ? int yaoqingma3 = 333; ? ? int x; ? ? scanf("%d", &x); ? ? if (x != yaoqingma1 && x != yaoqingma2 && x != yaoqingma3) { ? ? ? ? printf("無效邀請碼,請聯(lián)系導員:\n"); ? ? ? ? setbuf(stdin, NULL); ? ? ? ? menu(); ? ? } ? ? if (x == 111 || x ==222 || x == 333) { ? ? ? ? printf("please input the id with number:"); ? ? ? ? char id[20]; ? ? ? ? char id1[20]; ? ? ? ? char id2[20]; ? ? ? ? char id3[20] = "\n"; ? ? ? ? char id4[20] = "0"; ? ? ? ? char id6[20]; ? ? ? ? scanf("%s", id); ? ? ? ? printf("please input the password:"); ? ? ? ? scanf("%s", id1); next1: ? ? ? ? if (x == 111) { ? ? ? ? ? ? strcpy(id2, qx1); ? ? ? ? ? ? printf("請輸入學號\n"); ? ? ? ? ? ? scanf("%s", id4); ? ? ? ? ? ? struct personid *p = Create(zhroad); ? ? ? ? ? ? while (p) { ? ? ? ? ? ? ? ? if (!strcmp(id4, p->classnum)) { ? ? ? ? ? ? ? ? ? ? printf("該學號已被注冊,按0返回上一層,任意鍵重新輸入\n"); ? ? ? ? ? ? ? ? ? ? setbuf(stdin, NULL); ? ? ? ? ? ? ? ? ? ? char a; ? ? ? ? ? ? ? ? ? ? a = getchar(); ? ? ? ? ? ? ? ? ? ? if (a == '0') { ? ? ? ? ? ? ? ? ? ? ? ? menu(); ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? setbuf(stdin, NULL); ? ? ? ? ? ? ? ? ? ? goto next1; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? p = p->next; ? ? ? ? ? ? } ? ? ? ? } else if (x == 222) { ? ? ? ? ? ? printf("請選擇您的班級\n"); ? ? ? ? ? ? printf("1.網(wǎng)絡(luò)1班\n"); ? ? ? ? ? ? printf("2.網(wǎng)絡(luò)2班\n"); ? ? ? ? ? ? printf("3.網(wǎng)絡(luò)3班\n"); ? ? ? ? ? ? printf("4.網(wǎng)絡(luò)4班\n"); ? ? ? ? ? ? printf("5.網(wǎng)絡(luò)5班\n"); ? ? ? ? ? ? scanf("%s", id6); ? ? ? ? ? ? if (id6[1] == '\0') { ? ? ? ? ? ? ? ? if (id6[0] == '1' || id6[0] == '2' || id6[0] == '3' || id6[0] == '4' || id6[0] == '5') { ? ? ? ? ? ? ? ? ? ? setbuf(stdin, NULL); ? ? ? ? ? ? ? ? ? ? strcpy(id4, id6); ? ? ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? ? ? setbuf(stdin, NULL); ? ? ? ? ? ? ? ? ? ? printf("該班級不存在.\n"); ? ? ? ? ? ? ? ? ? ? menu(); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? printf("該班級不存在\n"); ? ? ? ? ? ? ? ? setbuf(stdin, NULL); ? ? ? ? ? ? ? ? menu(); ? ? ? ? ? ? } ? ? ? ? ? ? strcpy(id2, qx2); ? ? ? ? } else if (x == 333) { ? ? ? ? ? ? strcpy(id2, qx3); ? ? ? ? } ? ? ? ? AppendDataToFile(zhroad, id); ? ? ? ? AppendDataToFile(zhroad, kong); ? ? ? ? AppendDataToFile(zhroad, id1); ? ? ? ? AppendDataToFile(zhroad, kong); ? ? ? ? AppendDataToFile(zhroad, id2); ? ? ? ? AppendDataToFile(zhroad, kong); ? ? ? ? AppendDataToFile(zhroad, id4); ? ? ? ? AppendDataToFile(zhroad, id3); ? ? ? ? printf("注冊成功請重新登陸!\n"); ? ? ? ? setbuf(stdin, NULL); ? ? ? ? menu(); ? ? } }
在進行學生注冊時,應(yīng)該對學生輸入的學號進行一個判斷,判斷該學號是否被注冊,若被注冊應(yīng)該重新輸入。
在進行老師注冊時,應(yīng)該讓老師選擇已有的班級,如果沒有則重新輸入。
在注冊成功后利用文件將已經(jīng)注冊的賬號存儲起來
學生界面的一些操作
學生主要可以進行下面幾種操作:
void studentmenu() { ? ? ? ?//學生操作界面 ? ? printf("-----[good afternoon student ]-----\n"); ? ? printf("1.查詢成績\n"); ? ? printf("2.查詢本班成績\n"); ? ? printf("3.成績分析\n"); ? ? printf("4.成績申訴\n"); ? ? printf("5.返回上一層:\n"); ? ? printf("0.退出系統(tǒng)\n"); ? ? printf("----------------------------------\n"); ? ? studentkeydown(); ? ? }
在最初寫代碼時,我是讓學生輸入自己的學號來進行成績查詢,如果是考輸入學號來查詢的話,那么也可以輸入別人的成績,查詢別人班的成績,如果這樣寫,那學生的操作就和老師甚至管理員無異。
在最后修改代碼時,我將學生的學號和賬號綁定,在進行成績查詢等操作時,無需輸入自己的學號,
教師界面的一些操作
教師界面的主要功能如下
void teachermenu() { ? ? ? ? ? //老師操作界面 ? ? printf("-----[good afternoon teacher]-----\n"); ? ? printf("1.增加新的學生信息\n"); ? ? printf("2.刪除學生信息\n"); ? ? printf("3.修改學生信息\n"); ? ? printf("4.查詢學生信息\n"); ? ? printf("5.輸出本班成績\n"); ? ? printf("6.成績分析\n"); ? ? printf("7.提醒管理員更新成績\n"); ? ? printf("8.返回上一層:\n"); ? ? printf("0.退出系統(tǒng)\n"); ? ? printf("----------------------------------\n"); ? ? setbuf(stdin, NULL); ? ? teacherkeydown(); }
在一開始寫代碼時,和上面的學生操作類似,我是讓老師輸入班級或者老師輸入學號來進行相關(guān)操作的,這樣書寫的話老師就成為了一個萬能老師,可以查詢文件中所存儲的所有學生信息,現(xiàn)實中不存在教整個學校的老師,并且這樣與管理員的功能沖突。
在后來修改代碼時,我在老師注冊時讓老師選擇了班級,我們將這個班級與老師的賬號綁定,并且規(guī)定老師只能查詢自己班學生的成績,若輸入其他班的成績,則會進行相應(yīng)的錯誤提醒。
老師操作界面代碼如下:
void teacherkeydown() { //教師輸入選擇界面 ? ? char *x; ? ? char *a; ? ? x = allclassnum; ? ? struct student *temp1 = NULL; ? ? char str2[200]; ? ? char str1[100]; ? ? setbuf(stdin, NULL); ? ? scanf("%s", str1); ? ? if (str1[1] == '\0') { ? ? ? ? switch (str1[0]) { ? ? ? ? ? ? case '0': ? ? ? ? ? ? ? ? exit(0); ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? case '1': ? ? ? ? ? ? ? ? a = classnum(x); ? ? ? ? ? ? ? ? temp1 = mescreate(a); ? ? ? ? ? ? ? ? temp1 = addnode(temp1); ? ? ? ? ? ? ? ? writetoclassfile(temp1, a); ? ? ? ? ? ? ? ? teachermenu(); ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? case '2': ? ? ? ? ? ? ? ? a = classnum(x); ? ? ? ? ? ? ? ? temp1 = mescreate(a); ? ? ? ? ? ? ? ? temp1 = delnode(temp1); ? ? ? ? ? ? ? ? writetoclassfile(temp1, a); ? ? ? ? ? ? ? ? teachermenu(); ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? case '3': ? ? ? ? ? ? ? ? a = classnum(x); ? ? ? ? ? ? ? ? temp1 = mescreate(a); ? ? ? ? ? ? ? ? temp1 = changenode(temp1); ? ? ? ? ? ? ? ? writetoclassfile(temp1, a); ? ? ? ? ? ? ? ? teachermenu(); ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? case '4': ? ? ? ? ? ? ? ? printf("please input student studyid:\n"); ? ? ? ? ? ? ? ? char studyid[20]; ? ? ? ? ? ? ? ? scanf("%s", studyid); ? ? ? ? ? ? ? ? if (studyid[1] == allclassnum[0] && studyid[0] == '0' && strlen(studyid) < 6) { ? ? ? ? ? ? ? ? ? ? printpersonnalsocre(studyid); ? ? ? ? ? ? ? ? ? ? teachermenu(); ? ? ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? ? ? printf("不是您的學生或者學號不存在\n"); ? ? ? ? ? ? ? ? ? ? teachermenu(); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ?? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? case '5': ? ? ? ? ? ? ? ? a = classnum(x); ? ? ? ? ? ? ? ? temp1 = mescreate(a); ? ? ? ? ? ? ? ? temp1 = sort4(temp1); ? ? ? ? ? ? ? ? Printall(temp1); ? ? ? ? ? ? ? ? setbuf(stdin, NULL); ? ? ? ? ? ? ? ? teachermenu(); ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? case '6': ? ? ? ? ? ? ? ? a = classnum(x); ? ? ? ? ? ? ? ? temp1 = mescreate(a); ? ? ? ? ? ? ? ? chengjifenxi(temp1); ? ? ? ? ? ? ? ? teachermenu(); ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? case '7': ? ? ? ? ? ? ? ? FILE *fp1; ? ? ? ? ? ? ? ? fp1 = fopen(shensu, "w"); ? ? ? ? ? ? ? ? printf("please input the wrong\n"); ? ? ? ? ? ? ? ? scanf("%s", str2); ? ? ? ? ? ? ? ? fprintf(fp1, "%s\n", str2); ? ? ? ? ? ? ? ? printf("您的提醒已經(jīng)發(fā)送!"); ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? case '8': ? ? ? ? ? ? ? ? menu(); ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? default: ? ? ? ? ? ? ? ? printf("輸入有誤請重新輸入\n"); ? ? ? ? ? ? ? ? teachermenu(); ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? } ? ? } else { ? ? ? ? printf("輸入有誤請重新輸入\n"); ? ? ? ? teachermenu(); ? ? } }
管理員的一些操作
管理員的主要功能如下:
void guanlidaiban() { ? ? printf("-----[good afternoon manager ]----\n"); ? ? printf("1.密碼注冊\n"); ? ? printf("2.密碼修改\n"); ? ? printf("3.密碼找回\n"); ? ? printf("4.成績申訴\n"); ? ? printf("5.更新成績庫\n"); ? ? printf("0.退出系統(tǒng)\n"); ? ? printf("----------------------------------\n"); ? ? keydowmdaiban(); } void guanlimenu() { ? ? printf("-----[good afternoon manager ]----\n"); ? ? printf("1.代辦選項\n"); ? ? printf("2.增加賬號和密碼\n"); ? ? printf("3.刪除賬號和密碼\n"); ? ? printf("4.修改賬號和密碼\n"); ? ? printf("5.輸出所有賬號和密碼\n"); ? ? printf("6.錄入所有的賬號和密碼\n"); ? ? printf("7.進入教師用戶端\n"); ? ? printf("a.返回上一層\n"); ? ? printf("0.退出系統(tǒng)\n"); ? ? printf("----------------------------------\n"); ? ? guanlikeydown(); }
管理員相比較于教師,可以對賬號進行操作,并且可以查詢所有班的成績,在最開始設(shè)計時,我將管理員的操作寫的跟學生教師沖突,尤其是進入教師用戶端,進入教師用戶端的代碼如下。
printf("請選擇您想進行操作的班級\n"); ? ? ? ? ? ? ? ? printf("1.網(wǎng)絡(luò)1班\n"); ? ? ? ? ? ? ? ? printf("2.網(wǎng)絡(luò)2班\n"); ? ? ? ? ? ? ? ? printf("3.網(wǎng)絡(luò)3班\n"); ? ? ? ? ? ? ? ? printf("4.網(wǎng)絡(luò)4班\n"); ? ? ? ? ? ? ? ? printf("5.網(wǎng)絡(luò)5班\n"); ? ? ? ? ? ? ? ? scanf("%s", choice1); ? ? ? ? ? ? ? ? if (choice1[1] != '\0') { ? ? ? ? ? ? ? ? ? ? printf("班級不存在請重新輸入\n"); ? ? ? ? ? ? ? ? ? ? goto ?next1; ? ? ? ? ? ? ? ? } else if (choice1[0] == '1' || choice1[0] == '2' || choice1[0] == '3' || choice1[0] == '4' || choice1[0] == '5') { ? ? ? ? ? ? ? ? ? ? allclassnum[0] = choice1[0]; ? ? ? ? ? ? ? ? ? ? teachermenu(); ? ? ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? ? ? printf("班級不存在請重新輸入\n"); ? ? ? ? ? ? ? ? ? ? goto ?next1; ? ? ? ? ? ? ? ? }
管理員可以選擇班級進行查看,當管理員選擇后我將全局變量allclassnum(記錄教師班級)改成了相對應(yīng)操作的班級然后進入教師端。
總結(jié)
最開始寫管理系統(tǒng)時沒有注意很多細節(jié),并且邏輯不合理,導致剛剛寫完時非常的拉垮,在以后寫程序時一定會多多留心。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Eclipse中C++連接mysql數(shù)據(jù)庫
這篇文章主要為大家詳細介紹了Eclipse中C++連接mysql數(shù)據(jù)庫 ,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-06-06深入理解C++中的new和delete并實現(xiàn)對象池
這篇文章主要介紹了C++中的new和delete并實現(xiàn)對象池,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-09-09C++字符串拼接效率對比(+=、append、stringstream、sprintf)
這篇文章主要介紹了C++字符串拼接效率對比(+=、append、stringstream、sprintf),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-08-08C++17 使用 std::string_view避免字符串拷貝優(yōu)化程序性能
這篇文章主要介紹了C++17 使用 std::string_view避免字符串拷貝優(yōu)化程序性能,幫助大家提高程序運行速度,感興趣的朋友可以了解下2020-10-10