您好,登錄后才能下訂單哦!
小編給大家分享一下C語言實現學生成績管理系統的示例分析,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
學生成績管理系統實現的功能有:成績錄入、學生成績查詢、刪除、修改、通過文件保存等。
開發這樣一個系統需要具備的知識:線性表(鏈表)、文件操作、排序(如果需要成績排序)。
開發環境為VS2015;在Linux下沒有conio.h的頭文件,需要修改與getch()函數相關的代碼。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <conio.h> /*學生信息結構體*/ typedef struct Node { char Name[10]; //學生姓名 char ID[15]; //學生學號 int Score[3]; //三科成績(數學、英語、數據結構) float Ave_Sco; struct Node *next; }Lnode; void Display(); /*界面顯示函數*/ void GetScore(Lnode *&h); /*成績錄入函數*/ void PrintScore(Lnode *h); /*成績打印函數*/ void ModifyScore(Lnode *h); /*成績修改函數*/ void FindInf(Lnode *h); /*查找信息*/ void Delete(Lnode *h); /*刪除函數*/ void Quit(Lnode *h); /*退出函數*/ void SaveInf(Lnode *h); void LoadInf(Lnode *h); /*初始化鏈表*/ void InitList(Lnode *&head) { head = (Lnode *)malloc(sizeof(Lnode)); if (head == NULL) { printf("error!"); exit(1); } head->next = NULL; //使頭節點指針域為空 } int main() { Lnode *ScoreList; //建立成績鏈表,所有學生信息存放在此鏈表 int Function; char flag; int t = 0; InitList(ScoreList); LoadInf(ScoreList); while (1) { Display(); printf("請選擇操作: "); scanf("%d", &Function); switch (Function) { case 1: while (1) { GetScore(ScoreList); printf("是否繼續輸入 (Y/N)"); scanf("%s", &flag); if (flag == 'N' || flag == 'n')break; } system("cls"); break; case 2: PrintScore(ScoreList); _getch(); system("cls"); break; case 3: ModifyScore(ScoreList); system("cls"); break; case 4: FindInf(ScoreList); _getch(); system("cls"); break; case 5: Delete(ScoreList); _getch(); system("cls"); break; case 6: Quit(ScoreList); break; default: printf("Error!!! 請重新輸入:"); break; } //switch結束 } return 0; } /*系統界面顯示*/ void Display() { printf("\t\t**********************************************\n"); printf("\t\t*************歡迎使用成績管理系統*************\n"); printf("\t\t**********************************************\n"); printf("\t\t\t\t1、錄入成績\n"); printf("\t\t\t\t2、打印成績\n"); printf("\t\t\t\t3、修改成績\n"); printf("\t\t\t\t4、查找學生信息\n"); printf("\t\t\t\t5、刪除學生信息\n"); printf("\t\t\t\t6、退出系統\n"); printf("\n\n\n\n\n\n"); } /*成績錄入*/ void GetScore(Lnode *&h) { Lnode *p, *q = h; char name[10], id[15]; int Math, English, Datastruct; p = (Lnode *)malloc(sizeof(Lnode)); //為學生信息申請節點 printf("請依次輸入學生信息:\n"); printf("姓名 學號 數學 英語 數據結構\n"); scanf("%s %s %d %d %d", &name, &id, &Math, &English, &Datastruct); for (; q->next != NULL; q = q->next){;} //移動到尾節點 strcpy(p->Name, name); strcpy(p->ID, id); p->Score[0] = Math; p->Score[1] = English; p->Score[2] = Datastruct; p->Ave_Sco = ((float)((p->Score[0] + p->Score[1] + p->Score[2]) - 150)) / 30; p->next = NULL; q->next = p; q = p; } /*成績打印*/ void PrintScore(Lnode *h) { Lnode *p = h->next; printf("%-14s%-8s%-8s%-8s%-8s%-8s\n","排名", "學號", "姓名", "數學", "英語", "數據結構", "平均績點"); while (p != NULL) { printf("%-14s%-8s%-8d%-8d%-8d%.2f\n", p->ID, p->Name, p->Score[0], p->Score[1], p->Score[2], p->Ave_Sco); p = p->next; } } /*成績修改*/ void ModifyScore(Lnode *h) { Lnode *p = h->next; char name[10], id[15]; int Math, English, Datastruct; printf("請輸入學生姓名:"); scanf("%s", name); printf("請輸入學生學號:"); scanf("%s", id); while (p) { if (strcmp(p->Name, name)==0 && strcmp(p->ID, id)==0) { printf("當前學生信息:\n"); printf("%-14s%-8s%-8s%-8s%-8s\n", "學號", "姓名", "數學", "英語", "數據結構"); printf("%-14s%-8s%-8d%-8d%-8d\n", p->ID, p->Name, p->Score[0], p->Score[1], p->Score[2]); printf("請輸入更正后的數學成績:"); scanf("%d", &Math); printf("請輸入更正后的英語成績:"); scanf("%d", &English); printf("請輸入更正后的數據結構成績:"); scanf("%d", &Datastruct); p->Score[0] = Math; p->Score[1] = English; p->Score[2] = Datastruct; break; } else { p = p->next; } }//while循環結束 } /*信息查找*/ void FindInf(Lnode *h) { Lnode *p = h->next; char name[10], id[15]; printf("請輸入學生姓名:"); scanf("%s", name); printf("請輸入學生學號:"); scanf("%s", id); while (p) { if (strcmp(p->Name, name) == 0 && strcmp(p->ID, id) == 0) { printf("當前學生信息:\n"); printf("%-14s%-8s%-8s%-8s%-8s\n", "學號", "姓名", "數學", "英語", "數據結構"); printf("%-14s%-8s%-8d%-8d%-8d\n", p->ID, p->Name, p->Score[0], p->Score[1], p->Score[2]); break; } else { p = p->next; } }//while循環結束 } /*刪除*/ void Delete(Lnode *h) { Lnode *p = h, *q; q = p->next; char name[10], id[15]; printf("請輸入學生姓名:"); scanf("%s", name); printf("請輸入學生學號:"); scanf("%s", id); while (q) { if (strcmp(q->Name, name) == 0 && strcmp(q->ID, id) == 0) { p->next = q->next; free(q); //刪除p節點 printf("刪除成功\n"); break; } else { p = p->next; q = q->next; } }//while循環結束 } /*退出系統*/ void Quit(Lnode *h) { SaveInf(h); //退出時保存信息 exit(0); } /*打開文件*/ void LoadInf(Lnode *h) { Lnode *p = h; Lnode *q; //臨時變量 用于保存從文件中讀取的信息 FILE* file = fopen("./Information.dat", "rb"); if (!file) { printf("文件打開失敗!"); return ; } /* 使用feof判斷文件是否為結束要注意的問題: 當讀取文件結束時,feof函數不會立即設置標志符為-1,而是 需要再讀取一次后,才會設置。所以要先讀一次。 */ q = (Lnode *)malloc(sizeof(Lnode)); fread(q, sizeof(Lnode), 1, file); while (!feof(file)) //一直讀到文件末尾 { p->next = q; p = q; q = (Lnode *)malloc(sizeof(Lnode)); fread(q, sizeof(Lnode), 1, file); } //while循環結束 p->next = NULL; fclose(file); } /*保存信息到文件中*/ void SaveInf(Lnode *h) { Lnode *p = h->next; int flag; FILE* file = fopen("./Information.dat", "wb"); if (!file) { printf("文件打開失敗!"); return; } while (p != NULL) { flag = fwrite(p, sizeof(Lnode), 1, file); //將p的內容寫到文件中 if (flag != 1) { break; } p = p->next; } fclose(file); }
雖然是很簡單的小項目,還是有很多問題。
一:鏈表相關
在寫成績錄入和成績打印功能時,發現始終只能保存(沒加入文件保存)最后一個數據,確定鏈表的相關操作沒有問題,仔細判斷邏輯關系后,發現是每次在頭節點傳到GetScore()函數,為新節點申請內存后,直接將數據保存在了新申請的節點里面,沒有將鏈表移動到尾節點,導致每次錄入成績,都會覆蓋前一次輸入的數據。解決辦法是鏈表傳到函數后,先移動到最后一個節點,將新申請的節點掛接在最后一個節點之后。
/*成績錄入*/ void GetScore(Lnode *&h) { Lnode *p, *q = h; char name[10], id[15]; int Math, English, Datastruct; p = (Lnode *)malloc(sizeof(Lnode)); //為學生信息申請節點 printf("請依次輸入學生信息:\n"); printf("姓名 學號 數學 英語 數據結構\n"); scanf("%s %s %d %d %d", &name, &id, &Math, &English, &Datastruct); for (; q->next != NULL; q = q->next){;} //移動到尾節點 //保存數據 strcpy(p->Name, name); strcpy(p->ID, id); p->Score[0] = Math; p->Score[1] = English; p->Score[2] = Datastruct; p->Ave_Sco = ((float)((p->Score[0] + p->Score[1] + p->Score[2]) - 150)) / 30; //始終指向最后一個節點 p->next = NULL; q->next = p; q = p; }
二、文件操作
用文件保存遇到的問題主要是每次打印數據時除正常數據外,始終多一行亂碼。判斷方法是while(!feof(file))。排除錯誤時確定了兩種可能性:多保存了一行;多讀取了一行。經過某度feof()與EOF的關系后,確定是多讀取了一行數據。
用feof()函數進行文件尾判斷時,當文件已經到達尾部后,還需要在讀取一次后,feof()函數才會返回-1,所以會出現多讀一次的情況;解決辦法時,在循環讀取之前先將第一個數據讀取出來,然后在正常讀取。即注意多讀一次的問題。
/*打開文件*/ void LoadInf(Lnode *h) { Lnode *p = h; Lnode *q; //臨時變量 用于保存從文件中讀取的信息 FILE* file = fopen("./Information.dat", "rb"); if (!file) { printf("文件打開失敗!"); return ; } /* 使用feof判斷文件是否為結束要注意的問題: 當讀取文件結束時,feof函數不會立即設置標志符為-1,而是 需要再讀取一次后,才會設置。所以要先讀一次。 */ q = (Lnode *)malloc(sizeof(Lnode)); fread(q, sizeof(Lnode), 1, file); while (!feof(file)) //一直讀到文件末尾 { p->next = q; p = q; q = (Lnode *)malloc(sizeof(Lnode)); fread(q, sizeof(Lnode), 1, file); } //while循環結束 p->next = NULL; fclose(file); }
看完了這篇文章,相信你對“C語言實現學生成績管理系統的示例分析”有了一定的了解,如果想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。