簡單復(fù)習下C語言基礎(chǔ)知識,使用單鏈表,結(jié)構(gòu)體嵌套,文件讀寫信息,實現(xiàn)控制臺簡單學生成績管理系統(tǒng).
源碼
- 枚舉類型
#include<stdio.h>
#include <stdlib.h>
#include <string>
enum CONMMAND
{
SAVEANDQUIT, ADD, MODIFY, INUIRY, DELETE, BROWSE
};
- 相關(guān)結(jié)構(gòu)體與單鏈表結(jié)構(gòu)體
struct Results
{
int math;
int language;
int english;
int computer;
};
struct Student
{
char s_StuId[10]; // 學號
char s_Name[10]; // 姓名
char s_IDcard[20]; // 身份證號
char s_DateBirth[20]; // 出生日期
int s_Age; // 年齡
char s_Gender[3]; // 性別
Results re; // 各科成績
float s_result; // 成績
int s_rank = 1; // 排名
char s_Finalassess[10] = ""; // 最終評價
};
struct StudentLinklist
{
Student stu; // 數(shù)據(jù)域
StudentLinklist* next; // 指針域
};
- 全局操作指令與文件路徑
int nConmmand;
const char* file = "E:\\student\\saveLinklist.bin";
- 簡單的顯示菜單,以及錄入信息函數(shù)
// 菜單
void MenuFirst(int* nConmmand) {
printf("\n\n\n\t\t\t\t++#@%=================學生成績管理系統(tǒng)=================%@#++\n\n\n");
printf("\t\t\t\t\t1.添加學生成績信息\t2.修改學生成績信息\n\t\t\t\t\t3.查詢學生成績信息\t4.刪除學生成績信息\n\t\t\t\t\t5.瀏覽學生成績信息\t0.保存并退出系統(tǒng)\n");
printf("\n\n\t\t\t\t++#@%=================學生成績管理系統(tǒng)=================%@#++\n");
printf("請輸入你的指令(0-6):\n");
scanf_s("%d", nConmmand);
}
// 錄入學生信息.
Student mScanfstudent() {
Student stu;
printf("請輸入學生基本信息:\n");
printf("學號\t姓名\t身份證號\t出生日期\t年齡\t性別\n");
scanf("%s\t%s\t%s\t%s\t%d\t%s", stu.s_StuId, stu.s_Name, stu.s_IDcard, stu.s_DateBirth, &stu.s_Age, stu.s_Gender);
printf("請輸入學生基本成績信息:\n");
printf("數(shù)學\t語文\t英語\t計算機課程設(shè)計\n");
scanf("%d\t%d\t%d\t%d", &stu.re.math, &stu.re.language, &stu.re.english, &stu.re.computer);
stu.s_result = (stu.re.computer + stu.re.english + stu.re.language + stu.re.math) / 4;
return stu;
}
- 鏈表的各種操作函數(shù)
// 創(chuàng)建節(jié)點
StudentLinklist* mcretelink() {
StudentLinklist* H = (StudentLinklist*)malloc(sizeof(StudentLinklist));
if (!H)
{
printf("創(chuàng)建失敗");
getchar();
exit(0);
}
else { // 初始化
H->next = NULL;
}
return H;
}
// 遍歷返回鏈表長度
int mGetLinklist(StudentLinklist* stulink) {
StudentLinklist* temp = stulink;
int nLen = 0;
while (temp)
{
temp = temp->next;
nLen++;
}
return nLen;
}
// 在尾部插入stu信息.
void minsertend(StudentLinklist* stulink, Student stu) {
StudentLinklist* temp = stulink;
while (temp->next != NULL)
{
temp=temp->next;
}
StudentLinklist* s = mcretelink();
s->stu = stu;
s->next = temp->next;
temp->next = s;
}
- 鏈表遍歷操作函數(shù)(各種增,刪,改,查等操作)
// 遍歷輸出鏈表
void mPrintlinklist(StudentLinklist* stulink) {
StudentLinklist* temp = stulink->next;
Student stu;
printf("學號\t姓名\t身份證號\t\t出生日期\t年齡\t性別\t綜合成績\t排名\t總評\n");
while (temp!= NULL)
{
stu = temp->stu;
printf("%s\t%s\t%s\t%s\t%d\t%s\t%.1f\t\t%d\t%s\n", stu.s_StuId, stu.s_Name, stu.s_IDcard, stu.s_DateBirth, stu.s_Age, stu.s_Gender, stu.s_result, stu.s_rank, stu.s_Finalassess);
temp = temp->next;
}
}
//遍歷設(shè)置總評成績
bool mSetFinalassess(StudentLinklist* stulnk) {
StudentLinklist* temp = stulnk;
if (temp == NULL)
{
return 0;
}
while (temp)
{
if (60.0 <= temp->stu.s_result && temp->stu.s_result < 70.0)
{
strcpy(temp->stu.s_Finalassess, "合格");
}
else if (70.0 <= temp->stu.s_result && temp->stu.s_result< 90.0) {
strcpy(temp->stu.s_Finalassess, "優(yōu)良");
}
else if (90.0 <= temp->stu.s_result) {
strcpy(temp->stu.s_Finalassess, "優(yōu)秀");
}
else {
strcpy(temp->stu.s_Finalassess, "不合格");
}
temp = temp->next;
}
}
// 遍歷排序.
void mSort(StudentLinklist* stulinklist) {
StudentLinklist* temp = stulinklist->next;
Student p;
if (!temp) {
printf("信息為空\n");
}
else {
while (temp->next != NULL)
{
if (temp->stu.s_result < temp->next->stu.s_result)
{
p = temp->stu;
temp->stu = temp->next->stu;
temp->next->stu = p;
}
temp = temp->next;
}
}
}
// 遍歷設(shè)置排名
void mSetrank(StudentLinklist* stulinklist) {
StudentLinklist* temp = stulinklist;
int i = 0;
while (temp)
{
temp->stu.s_rank = i;
i++;
temp = temp->next;
}
}
//遍歷查詢通過學號
Student mInquire(StudentLinklist* stulinklist,char* stuid) {
StudentLinklist* temp = stulinklist;
Student stu;
while (temp)
{
if (strcmp(temp->stu.s_StuId,stuid)==0)
break;
else
temp = temp->next;
}
stu = temp->stu;
return stu;
}
// 刪除指定元素
bool mDelete(StudentLinklist* stulinklist,char* stuid){
StudentLinklist* temp=stulinklist;
while (temp->next)
{
if (strcmp(temp->next->stu.s_StuId, stuid) == 0)
break;
else
temp = temp->next;
}
// 創(chuàng)建一個新節(jié)點
StudentLinklist* s = mcretelink();
// 使s指向第i個位置(要刪除的位置)
s = temp->next;
//用stu參數(shù)暫時保存即將刪除的數(shù)據(jù).
//讓temp.next指向i后面的一位.
temp->next = s->next;
//刪除節(jié)點,釋放掉s指向的第i個位置的節(jié)點空間
free(s);
return 1; //刪除成功
}
// 修改指定元素
bool mModify(StudentLinklist* stulinklist,char* stuid,Student stu){
StudentLinklist* temp = stulinklist;
while (temp)
{
if (strcmp(temp->stu.s_StuId, stuid) == 0)
break;
else
temp = temp->next;
}
temp->stu = stu;
return 1;
}
- 文件讀寫函數(shù)(將鏈表數(shù)據(jù)寫入文件,與將文件的數(shù)據(jù)讀入到鏈表中).
讀寫模式采用覆蓋,所有數(shù)據(jù)只存入一條鏈表.
// 文件是無法保存一個鏈表指針域的.只能按數(shù)據(jù)塊來保存.所以需要單獨將鏈表
// 的數(shù)據(jù)域存進文件,讀取的時候再創(chuàng)建鏈表初始化即可.
// 將鏈表數(shù)據(jù)寫入文件..
bool mWriteLinklist(const char* file,StudentLinklist* stulinklist) {
FILE* fp;
StudentLinklist* temp = stulinklist->next;
fp = fopen(file, "rb+");
if (!fp)
{
return 0;
}
else {
// 將鏈表中的所有節(jié)點的數(shù)據(jù)域存放進文件中
while (temp)
{
fwrite(&temp->stu, sizeof(Student), 1, fp);
temp = temp->next;
}
return 1;
}
}
// 讀取文件中的數(shù)據(jù)到linklist中
bool mReadlinklist(const char* file,StudentLinklist* stulinklist) {
FILE* fp;
Student stu;
fp = fopen(file, "rb+");
if (!fp)
{
printf("打開失敗");
exit(1);
return 0;
}
else {
while (fread(&stu,sizeof(Student),1,fp))
{
StudentLinklist* s = mcretelink();
s->stu = stu;
s->next =stulinklist ->next;
stulinklist->next = s;
}
return 1;
}
}
- 主函數(shù)
int main()
{
// 先讀取文件,將鏈表取出.
StudentLinklist* stulinklist = mcretelink(); // 全局鏈表,只對它操作.
if (!mReadlinklist(file, stulinklist))
{
printf("讀取文件失敗");
}
char stuid[10]; //學號
Student stu; // 學生
char a;
while (1) {
MenuFirst(&nConmmand);
switch (nConmmand)
{
case ADD: // 添加
stu = mScanfstudent();
minsertend(stulinklist,stu);
system("cls");
break;
case MODIFY: // 修改
printf("請輸入要修改的學生的學號:");
scanf("%s", stuid);
stu = mScanfstudent();
if (mModify(stulinklist, stuid, stu))
{
printf("修改成功");
}
system("cls");
break;
case INUIRY: // 查詢
printf("請輸入查詢學號:");
scanf("%s", stuid);
stu = mInquire(stulinklist, stuid);
printf("%s\t%s\t%s\t%s\t%d\t%s\t%.1f\t\t%d\t%s\n", stu.s_StuId, stu.s_Name, stu.s_IDcard, stu.s_DateBirth, stu.s_Age, stu.s_Gender, stu.s_result, stu.s_rank, stu.s_Finalassess);
system("cls");
break;
case DELETE: // 刪除
printf("請輸入要刪除學生的學號:");
scanf("%s", stuid);
if (mDelete(stulinklist, stuid)) {
printf("刪除成功");
}
system("cls");
break;
case BROWSE: // 瀏覽
mSetFinalassess(stulinklist); // 設(shè)置總評
mSort(stulinklist); // 遍歷判斷,按成績排序
mSetrank(stulinklist); // 遍歷設(shè)置排名
mPrintlinklist(stulinklist); // 遍歷輸出鏈表.
break;
case SAVEANDQUIT: // 保存
mSetFinalassess(stulinklist); //設(shè)置總評
mSort(stulinklist); // 遍歷判斷,按成績排序
mSetrank(stulinklist); //遍歷設(shè)置排名
if (mWriteLinklist(file, stulinklist)) //判斷寫入是否成功,并退出程序.
{
printf("保存成功");
}
exit(0);
break;
default:
break;
};
}
}
圖片.png
圖片.png
當然,時間倉促,系統(tǒng)很簡陋,還有很多可以完善和改進的地方.只是重點回顧了一下指針,鏈表,結(jié)構(gòu)體,文件的一些常用操作.至于讀寫excel表格文件(格式化存儲),實現(xiàn)條件判斷自動分發(fā)郵件(網(wǎng)絡(luò)編程,sokect套接字,smtp協(xié)議).等技術(shù),之后有時間再寫吧.
2019.12.30日.