【前言】
寒假回家也沒閒著呀,花了4天晚上的時間完成了數據結構的課程設計。以我的觀點來看,這個東西大一就應該做了,無非就是結構體,鏈表,增,刪,查,改。坑爹是的,有三個不同的txt文件存放數據,有一種數據庫外鍵的感覺。總體來說仿佛回到了大一寫黑框框程序的日子了,又鞏固了C語言。不能說是浪費時間,收獲也不小,隱藏BUG還在探索當中。代碼寫的不算漂亮,肯定可以優化。
~ ~!。
【運行截圖】
【需求】
1.有三個文件Student.txt,Course.txt,SC.txt分別存放學生基本,課程,學生成績,程序運行時從這三個文件中讀取數據,程序關閉時更新這三個文件。
2.對學生進行查找,刪除,增添,修改等操作。
3.查詢時采用多樣查詢。
4.添加時數據的檢測。
【設計圖】
【代碼】
/*
* 課程設計:C語言版學生管理
* 作者:王小康
* 時間:2014-1-11
* 平台:windows
*/
#include
#include
#include
#include
#define LEN_COURSE sizeof(Course)
#define LEN_STUDENT sizeof(Student)
typedef struct Course {
int id; /*課程編號*/
char name[20]; /*課程名稱*/
int credit; /*課程學分*/
int grade; /*課程成績*/
Course *next; /*課程指針,1.記錄課程時所用,2.用於學生結構中*/
}Course;
typedef struct Student {
char num[10]; /*學號*/
char name[16]; /*姓名*/
char sex[10]; /*姓名*/
int age; /*年齡*/
char dept[20]; /*專業*/
Course *headCourse; /*學生所修的課程信息*/
Student *next; /*學生指針,指向下一個學生*/
}Student;
/*全局變量,程序啟動時加載三個文件夾,這兩個變量作為儲存數據的實體*/
Student *student = NULL;
Course *course = NULL;
/*讀取Student.txt文件中內容創建學生鏈表*/
Student* Creat_Student()
{
Student *head;
Student *p1,*p2;
p2 = (Student*)malloc(LEN_STUDENT);
head = p2;
FILE *fp;
if((fp = fopen("Student.txt","r")) == NULL)
{
printf("◎學生文件打開錯誤,請將Student.txt放置與程序同一目錄下!!!\n");
exit(0);
}
for(int i = 0; i<1; i++)
fscanf(fp,"%*[^\n]%*c"); //跳過第一行開始讀取
while (!feof(fp))
{
p1 = (Student*)malloc(LEN_STUDENT);
fscanf(fp,"%s%s%s%d%s",p1->num,p1->name,p1->sex,&p1->age,p1->dept);
p1->headCourse = (Course*)malloc(LEN_COURSE);
p1->headCourse->next = NULL;
p1->next = NULL;
p2->next = p1;
p2 = p1;
}
fclose(fp);
return head;
}
/*讀取Couse.txt文件內容創建課程鏈表*/
Course* Creat_Course()
{
Course *head;
Course *p1,*p2;
p2 = (Course*)malloc(LEN_COURSE);
head = p2;
FILE *fp;
if((fp = fopen("Course.txt","r")) == NULL)
{
printf("◎課程信息文件打開錯誤,請將Course.txt放置與程序同一目錄下!!!\n");
exit(0);
}
for(int i = 0; i<1; i++)
fscanf(fp,"%*[^\n]%*c"); //跳過第一行開始讀取
while (!feof(fp))
{
p1 = (Course*)malloc(LEN_COURSE);
fscanf(fp, "%d%s%d",&p1->id,p1->name,&p1->credit);
p1->next = NULL;
p2->next = p1;
p2 = p1;
}
fclose(fp);
return head;
}
/*讀取SC.txt完善學生信息*/
void Read_SC()
{
Student* FindStudentByNum(char s[]);
Course* FindCourseById(int n);
Student* stu =NULL;
Course* cou = NULL;
char s_num[10]; //儲存Snum
int c_id; //儲存Cid
int grade; //儲存Grade
FILE *fp;
if((fp = fopen("SC.txt","r")) == NULL)
{
printf("◎課程信息文件打開錯誤,請將Course.txt放置與程序同一目錄下!!!\n");
exit(0);
}
for(int i = 0; i<1; i++)
fscanf(fp,"%*[^\n]%*c"); //跳過第一行開始讀取
while (!feof(fp))
{
fscanf(fp,"%s%d%d",s_num,&c_id,&grade);
if((stu=FindStudentByNum(s_num)) != NULL && (cou=FindCourseById(c_id)) != NULL)
{
Course *p = stu->headCourse;
//指針移動到最後一個結點
while (p->next != NULL)
{
p = p->next;
}
p->next = (Course*)malloc(LEN_COURSE);
Course *q = p->next;
q->id = cou->id;
strcpy(q->name,cou->name);
q->credit = cou->credit;
q->grade = grade;
q->next = NULL;
}
}
fclose(fp);
}
/*根據學號查找學生,返回指向該學生的指針*/
Student* FindStudentByNum(char s[])
{
Student* p = student;
Student* temp = NULL;
while (p!=NULL)
{
if(strcmp(p->num,s) == 0)
{
temp = p;
break;
}
else
{
p = p->next;
}
}
return temp;
}
/*根據ID查找課程,返回指向該課程的指針*/
Course* FindCourseById(int n)
{
Course* p = course;
Course* temp = NULL;
while (p!=NULL)
{
if(n == p->id)
{
temp = p;
break;
}
else
{
p = p->next;
}
}
return temp;
}
/*根據Name查找課程,返回指向該課程的指針*/
Course* FindCourseByName(char name[])
{
Course* p = course;
Course* temp = NULL;
while (p!=NULL)
{
if(strcmp(name,p->name) == 0)
{
temp = p;
break;
}
else
{
p = p->next;
}
}
return temp;
}
/*輔助功能判斷這個學生是否存在*/
bool IsStudent(char num[])
{
Student *p = student->next;
bool flag = false;
while (p != NULL)
{
if(strcmp(p->num,num) == 0)
{
flag = true;
}
p = p->next;
}
return flag;
}
/*【1-1】添加基本數據*/
int Add_Inform()
{
Student *newStu = NULL;
Student *p = student;
char stu_num[10];
char stu_name[16];
char stu_sex[10];
int stu_age;
char stu_dept[20];
printf("\n---------◎請輸入學生基本信息--------\n");
printf("學號 姓名 性別 年齡 專業\n");
printf("-------------------------------------\n");
scanf("%s%s%s%d%s",stu_num,stu_name,stu_sex,&stu_age,stu_dept);
if(strcpy(stu_sex,"男") != 0 && strcpy(stu_sex,"女"))
{
printf("◎性別不可亂填!!!\n");
return 0;
}
if(!IsStudent(stu_num))
{
newStu = (Student*)malloc(LEN_STUDENT);
strcpy(newStu->num,stu_num);
strcpy(newStu->name,stu_name);
strcpy(newStu->sex,stu_sex);
newStu->age = stu_age;
strcpy(newStu->dept,stu_dept);
newStu->headCourse = (Course*)malloc(LEN_COURSE);
newStu->headCourse->next = NULL;
newStu->next = NULL;
for(p=p->next; p->next!=NULL; p=p->next);
p->next = newStu;
printf("\n◎學生信息已成功添加◎\n");
}
else
{
printf("\n◎該學號學生已存在請檢查學號重新填寫◎\n");
}
return 0;
}
/*【1-2】添加成績*/
int Add_Grade()
{
Student *p1 = student->next;
char stu_num[10];
printf("\n◎請輸入您要添加成績的學號信息:");
scanf("%s",stu_num);
while(p1 != NULL)
{
if(strcmp(p1->num,stu_num) == 0)
{
Course *pc;
int cou_id;
char cou_name[20];
int cou_credit;
int cou_grade;
for(pc = p1->headCourse; pc->next!=NULL; pc=pc->next);
printf("\n----◎請輸入課程成績----\n");
printf("課程名稱 成績 \n");
printf("--------------------------\n");
scanf("%s%d",cou_name,&cou_grade);
if(cou_grade > 100 || cou_grade < 0)
{
printf("◎成績填寫錯誤!!!\n");
return 0;
}
Course *pc1;
Course *newCou;
if((pc1 = FindCourseByName(cou_name)) != NULL)
{
newCou = (Course*)malloc(LEN_COURSE);
newCou->id = pc1->id;
strcpy(newCou->name,cou_name);
newCou->credit = pc1->credit;
newCou->grade = cou_grade;
newCou->next = NULL;
pc->next = newCou;
printf("\n◎學生成績已成功添加◎\n");
}
else
{
printf("\n◎需要添加的課程在課程數據庫中不存在,請先添加這一課程◎\n");
}
return 0;
}
p1 = p1->next;
}
printf("數據庫中不存在您要添加學生的信息 ~~~");
printf("\n\n");
return 0;
}
/*【1-3】添加可選課程*/
int Add_Class()
{
Course *pc = course;
int cou_id;
char cou_name[20];
int cou_credit;
printf("\n----◎請輸入課程信息----\n");
printf("編號 課程名稱 學分\n");
printf("------------------------\n");
scanf("%d%s%d",&cou_id,cou_name,&cou_credit);
if(FindCourseById==NULL || FindCourseByName==NULL)
{
for(; pc->next!=NULL; pc=pc->next);
Course *newCou = (Course*)malloc(LEN_COURSE);
newCou->id = cou_id;
strcpy(newCou->name,cou_name);
newCou->credit = cou_credit;
newCou->next = NULL;
pc->next = newCou;
printf("\n◎可選課程已成功添加◎\n");
}
else
{
printf("\n◎數據庫中該課程已存在\n\n");
}
return 0;
}
/*【2-1】全量查詢*/
void Print_Inquire_All()
{
void menu_print_out();
Student *p1 = student->next;
menu_print_out();
while (p1!=NULL)
{
printf("%s\t%s\t%s\t%d\t%s ",p1->num,p1->name,p1->sex,p1->age,p1->dept);
Course *q = p1->headCourse->next;
while (q!=NULL)
{
printf("%s: %d ",q->name,q->grade);
q = q->next;
if(q == NULL)
{
printf("\n");
}
}
p1 = p1->next;
}
}
/*【2-2】按學號查詢*/
int Print_Inquire_Num()
{
void menu_print_out();
Student *p1 = student->next;
char stu_num[20];
printf("◎請輸入您需要查詢的學號:");
scanf("%s",stu_num);
while (p1!=NULL)
{
if(strcmp(p1->num,stu_num) == 0)
{
menu_print_out();
printf("%s\t%s\t%s\t%d\t%s ",p1->num,p1->name,p1->sex,p1->age,p1->dept);
Course *q = p1->headCourse->next;
while (q!=NULL)
{
printf("%s: %d ",q->name,q->grade);
q = q->next;
if(q == NULL)
{
printf("\n\n");
}
}
return 0;
}
p1 = p1->next;
}
printf("\n◎數據庫中不存在您要查詢的數據 ~~~");
printf("\n\n");
return 0;
}
/*【2-3】按姓名查詢*/
int Print_Inquire_Name()
{
void menu_print_out();
Student *p1 = student->next;
char stu_name[20];
printf("◎請輸入您需要查詢的姓名:");
scanf("%s",stu_name);
while (p1!=NULL)
{
if(strcmp(p1->name,stu_name) == 0)
{
menu_print_out();
printf("%s\t%s\t%s\t%d\t%s ",p1->num,p1->name,p1->sex,p1->age,p1->dept);
Course *q = p1->headCourse->next;
while (q!=NULL)
{
printf("%s: %d ",q->name,q->grade);
q = q->next;
if(q == NULL)
{
printf("\n\n");
}
}
return 0;
}
p1 = p1->next;
}
printf("\n◎數據庫中不存在您要查詢的數據 ~~~");
printf("\n\n");
return 0;
}
/*【2-4】模糊查詢*/
int Print_Inquire_Fuzze()
{
//TODO:根據關鍵字查詢
void menu_print_out();
Student *p1 = student->next;
char find[20];
int m = 0;
printf("◎請輸入您需要查詢的關鍵字:");
scanf("%s",find);
while (p1 != NULL)
{
if(strstr(p1->num,find) != 0 || strstr(p1->name,find) != 0 || strstr(p1->sex,find) != 0
|| strstr(p1->dept,find) != 0)
{
menu_print_out();
m = 1;
printf("%s\t%s\t%s\t%d\t%s ",p1->num,p1->name,p1->sex,p1->age,p1->dept);
Course *q = p1->headCourse->next;
while (q!=NULL)
{
printf("%s: %d ",q->name,q->grade);
q = q->next;
if(q == NULL)
{
printf("\n\n");
}
}
}
p1 = p1->next;
}
if(m == 0)
{
printf("\n◎數據庫中不存在您要查詢的數據 ~~~");
printf("\n\n");
}
return 0;
}
/*【2-5】全部課程*/
int Print_Course_All()
{
void course_print_out();
Course *pc = course->next;
course_print_out();
while (pc != NULL)
{
printf("%d\t%s\t%d\n",pc->id,pc->name,pc->credit);
pc = pc->next;
}
return 0;
}
/*【3-1】修改數據-刪除*/
int Delete()
{
Student *p1, *p2, *head;
char stu_num[10];
printf("\n◎請輸入您要刪除的學號信息:");
scanf("%s",stu_num);
p1 = student;
p2 = p1->next;
while (p2 != NULL)
{
if(strcmp(p2->num,stu_num) == 0)
{
p1->next = p2->next;
Course *pc1, *temp;
pc1 = p2->headCourse;
while (pc1 != NULL)
{
temp = pc1;
pc1 = pc1->next;
free(temp);
}
free(p2);
printf("\n\n◎已成功刪除指定數據◎\n");
return 0;
}
p2 = p2->next;
p1 = p1->next;
}
printf("數據庫中不存在您要修改的數據 ~~~");
printf("\n\n");
return 0;
}
/*【3-2】修改數據-修改基本信息*/
int Ament_N_S_A()
{
Student *p1 = student->next;
char stu_num[10];
printf("\n◎請輸入您要修改的學號信息:");
scanf("%s",stu_num);
while (p1 != NULL)
{
if(strcmp(p1->num,stu_num) == 0)
{
printf("------------------\n");
printf("姓名 性別 年齡 \n");
printf("------------------\n");
scanf("%s%s%d",p1->name,p1->sex,&p1->age);
printf("\n\n◎已成功修改指定學生基本信息◎\n");
return 0;
}
p1 = p1->next;
}
printf("數據庫中不存在您要修改的數據 ~~~");
printf("\n\n");
return 0;
}
/*【3-3】修改數據-修改成績*/
int Ament_Grade()
{
Student *p1 = student->next;
char stu_num[10];
printf("\n◎請輸入您要修改的學號信息:");
scanf("%s",stu_num);
while (p1 != NULL)
{
if(strcmp(p1->num,stu_num) == 0)
{
printf("可以修改的成績: ");
Course *cou[10];
Course *pc1 = p1->headCourse->next;
int i = 0, length = 0;
while (pc1 != NULL)
{
cou[i] = pc1;
printf("%s ",pc1->name);
i++;
length++;
pc1 = pc1->next;
}
printf("\n");
printf("請輸入各科新成績: ");
for(i = 0; i < length; i++)
{
scanf("%d",&cou[i]->grade);
}
printf("\n\n◎已成功修改指定學生成績◎\n");
return 0;
}
p1 = p1->next;
}
printf("數據庫中不存在您要修改的數據 ~~~");
printf("\n\n");
return 0;
}
/*輸出提示框*/
void menu_print_out()
{
printf("\n--------------------------------------------------------------------------------\n");
printf("學號 姓名 性別 年齡 專業 各科成績....\n");
printf("--------------------------------------------------------------------------------\n");
}
void course_print_out()
{
printf("\n---------------------------------\n");
printf("編號 課程名稱 學分\n");
printf("---------------------------------\n");
}
/*主菜單*/
void menu(void)
{
void ReadBack();
void menu_add(void);
void menu_inquire(void);
void menu_amend(void);
printf(" ╭════════╮ \n");
printf("╭══════╣學生管理系統V1.0╠══════╮\n");
printf("║ ╰════════╯ ║\n");
printf("║ 【1】添加數據 【3】修改數據 ║\n");
printf("║ ║\n");
printf("║ 【2】查詢數據 【4】退出系統 ║\n");
printf("║ ║\n");
printf("╰══════════════════════╯\n");
printf("◎請輸入功能前的序號進入相應的工具:【 】\b\b");
int a = 0;
a = getchar();
while(a!='1'&&a!='2'&&a!='3'&&a!='4')
{
printf("error! please input the right number!\n");
putchar('\a');
getchar();
printf("◎請重新輸入功能前的序號進入相應的工具:【 】\b\b");
a = getchar();
}
switch(a)
{
case '1':
menu_add();
break;
case '2':
menu_inquire();
break;
case '3':
menu_amend();
break;
case '4':
ReadBack();
exit(0);
break;
}
getchar();
}
/*二級菜單之添加數據*/
void menu_add(void)
{
system("cls");
getchar();
printf(" ╭════════╮ \n");
printf("╭══════╣ 添加數據方式 ╠═══════╮\n");
printf("║ ╰════════╯ ║\n");
printf("║ 【1】增添學生 【3】增添可選課程 ║\n");
printf("║ ║\n");
printf("║ 【2】增添成績 【4】返回菜單 ║\n");
printf("║ ║\n");
printf("╰═══════════════════════╯\n");
printf("◎請輸入功能前的序號進入相應的工具:【 】\b\b");
int a = 0;
a = getchar();
while(a!='1'&&a!='2'&&a!='3'&&a!='4')
{
printf("error! please input the right number!\n");
putchar('\a');
getchar();
printf("◎請重新輸入功能前的序號進入相應的工具:【 】\b\b");
a = getchar();
}
switch(a)
{
case '1':
system("cls");
Add_Inform();
system("pause");
system("cls");
menu_add();
break;
case '2':
system("cls");
Add_Grade();
system("pause");
system("cls");
menu_add();
break;
case '3':
system("cls");
Add_Class();
system("pause");
system("cls");
menu_add();
break;
case '4':
system("cls");
getchar();
menu();
break;
}
}
/*二級菜單之查詢數據*/
void menu_inquire(void)
{
system("cls");
getchar();
while(1)
{
system("cls");
printf(" ╭════════╮ \n");
printf("╭══════╣ 查詢數據方式 ╠══════╮\n");
printf("║ ╰════════╯ ║\n");
printf("║ 【1】全量查詢 【4】模糊查詢 ║\n");
printf("║ ║\n");
printf("║ 【2】學號查詢 【5】全部課程 ║\n");
printf("║ ║\n");
printf("║ 【3】姓名查詢 【6】返回菜單 ║\n");
printf("╰══════════════════════╯\n");
printf("◎請輸入功能前的序號進入相應的工具:【 】\b\b");
int a = 0;
a = getchar();
while(a!='1'&&a!='2'&&a!='3'&&a!='3'&&a!='4'&&a!='5'&&a!='6')
{
printf("error! please input the right number!\n");
putchar('\a');
getchar();
printf("◎請重新輸入功能前的序號進入相應的工具:【 】\b\b");
a = getchar();
}
switch(a)
{
case '1':
system("cls");
Print_Inquire_All();
system("pause");
getchar();
break;
case '2':
system("cls");
Print_Inquire_Num();
system("pause");
getchar();
break;
case '3':
system("cls");
Print_Inquire_Name();
system("pause");
getchar();
break;
case '4':
system("cls");
Print_Inquire_Fuzze();
system("pause");
getchar();;
break;
case '5':
system("cls");
Print_Course_All();
system("pause");
getchar();
break;
case '6':
system("cls");
getchar();
menu();
break;
}
}
}
/*二級菜單之修改數據*/
void menu_amend(void)
{
system("cls");
getchar();
while(1)
{
system("cls");
printf(" ╭════════╮ \n");
printf("╭══════╣ 修改數據方式 ╠══════╮\n");
printf("║ ╰════════╯ ║\n");
printf("║ 【1】刪除學生 【3】修改成績 ║\n");
printf("║ ║\n");
printf("║ 【2】修改學生 【4】返回菜單 ║\n");
printf("║ ║\n");
printf("╰══════════════════════╯\n");
printf("◎請輸入功能前的序號進入相應的工具:【 】\b\b");
int a = 0;
a = getchar();
while(a!='1'&&a!='2'&&a!='3'&&a!='4')
{
printf("error! please input the right number!\n");
putchar('\a');
getchar();
printf("◎請重新輸入功能前的序號進入相應的工具:【 】\b\b");
a = getchar();
}
switch(a)
{
case '1':
char flag[2];
printf("\n◎真的要進行刪除嗎?y/n :");
scanf("%s",flag);
if(strcmp(flag,"y") == 0)
{
system("cls");
Delete();
}
system("pause");
getchar();
break;
case '2':
system("cls");
Ament_N_S_A();
system("pause");
getchar();
break;
case '3':
system("cls");
Ament_Grade();
system("pause");
getchar();
break;
case '4':
system("cls");
getchar();
menu();
break;
}
}
}
/*退出程序時將數據寫回Student.txt,Course.txt,SC.txt進行更新*/
void ReadBack()
{
FILE *stu = fopen("Student.txt","w");
FILE *cou = fopen("Course.txt","w");
FILE *sc = fopen("SC.txt","w");
Student *sp = student->next;
Course *cp = course->next;
fprintf(stu,"Sno Sname Ssex Sage Sdept");
fprintf(cou,"Cid Cname Ccredit");
fprintf(sc,"Sno Cid Grade");
while (sp != NULL)
{
fprintf(stu,"\n%s %s %s %d %s",sp->num,sp->name,sp->sex,sp->age,sp->dept);
Course *cp1 = sp->headCourse->next;
while (cp1 != NULL)
{
fprintf(sc,"\n%s %d %d",sp->num,cp1->id,cp1->grade);
cp1 = cp1->next;
}
sp = sp->next;
}
while (cp != NULL)
{
fprintf(cou,"\n%d %s %d",cp->id,cp->name,cp->credit);
cp = cp->next;
}
fclose(stu);
fclose(cou);
fclose(sc);
}
/*初始化函數*/
void Lunch()
{
student = Creat_Student();
course = Creat_Course();
Read_SC();
menu();
}
void main()
{
SetConsoleTitle(L"C語言學生信息管理系統");
Lunch();
}
【總結】
總體上算是把大一的內容運用了一邊,大一基本上也就是寫寫100行左右的算法,沒寫過這個長的程序。還是要吐槽一下出題的老師,干嘛要用三個文件。不會是為下學期學數據庫做准備吧。還有,程序的算法非常直白,這也是導致寫這麼多的原因。最後最後,2014,大二下學期,還是要繼續努力,碼農之路還很長。。。。