一、本設計涉及的重要C語言知識有:
1.單鏈表的各種操作
2.文件流的操作
3.單鏈表的排序
二、本設計主要以下幾個模塊組成
1.學生成績添加模塊
2.學生成績刪除模塊
3.學生成績修改模塊
4.學生成績檢索模塊
5.學生成績顯示模塊(包括成績排序)
6.學生成績保存模塊
效果圖:
本設計大概5、6百行代碼左右,通過這個設計,本人感覺C語言熟練了很多,希望能對像我一樣的C語言菜鳥同學會有點幫助,廢話少說,咱們上代碼!
三、程序代碼
1.main.c
這個文件內主要完成主菜單的跳轉和接受用戶信息完成到各個模塊的跳轉。
<span style="font-size:16px;">#include <stdio.h>
#include "students.h"
int select_menu(void);
void hand_menu(int cmd, int *flag);
void quit();
int main(int argc, char *argv[])
{
int cmd;
int flag = 0;
while(1){
cmd = select_menu();
hand_menu(cmd, &flag);
}
}
int select_menu(void)
{
int select = 0;
printf("**************************************************************\n\n");
printf(" 學生管理系統 \n");
printf(" 1:添加學生信息 2:刪除學生信息\n");
printf(" 3:修改學生信息 4:查詢學生信息\n");
printf(" 5:查看學生信息 6:保存\n");
printf(" 0:退出\n\n");
printf("**************************************************************\n");
printf("請選擇:");
select=getch();
while(select<'0'||select>'6'){
printf("\n輸入錯誤,請重新選擇:");
select=getch();
}
return select;
}
void hand_menu(int cmd, int *flag)
{
static STU *stu_head = NULL;
if(*flag == 0){
stu_head = init_student(stu_head);
*flag = 1;
}
switch(cmd){
case '0':
save_student(stu_head);
quit();
break;
case '1':
system("cls");
stu_head = add_student(stu_head);
system("cls");
break;
case '2':
system("cls");
stu_head = del_student(stu_head);
system("cls");
break;
case '3':
system("cls");
modify_student(stu_head);
system("cls");
break;
case '4':
system("cls");
search_student(stu_head);
system("cls");
break;
case '5':
system("cls");
stu_head = display_student(stu_head);
system("cls");
break;
case '6':
system("cls");
save_student(stu_head);
system("cls");
break;
default:
break;
}
}
void quit()
{
printf("\n感謝使用學生管理系統!\n");
exit(0);
}
</span>
2.students.h
這個文件主要包含students.c文件函數操作所需的定義。
#ifndef _STUDENTS_H_
#define _STUDENTS_H_
typedef struct st{
unsigned long ID;
char name[10];
float chinese;
float math;
float english;
double all_sub;
float average;
struct st* next;
}STU;
#define ASK_STU(p) do{p=(STU *)malloc(sizeof(STU));\
if(p==NULL){printf("malloc memory failed!\n");exit(1);}\
}while(0)
STU *search_by_nb(STU *stu_head, unsigned long nb);
STU *search_by_name(STU *stu_head, char name[]);
STU *select_sort(STU *g, char flag);
STU *add_student(STU *stu_head);
STU *del_all(STU *stu_head);
STU *del_one(STU *stu_head, int flag);
STU *del_student(STU *stu_head);
void modify_student(STU *stu_head);
STU *display_student(STU *stu_head);
STU *search_by_name(STU *stu_head, char name[]);
STU *search_by_nb(STU *stu_head, unsigned long nb);
#endif
3.store.h
#ifndef _STORE_H_
#define _STORE_H_
void save_student(STU *stu_head);
STU *init_student(STU *stu_head);
#endif
4.students.c
這個文件是本設計的核心部分,包括各個模塊的實現函數,包括添加,刪除,修改,查找,顯示學生信息這幾個模塊的實現。
<span style="font-size:16px;">#include <stdio.h>
#include "students.h"
STU *select_sort(STU *g, char flag)
{
STU *p,*q,*t,*s,*h;
h=(STU *)malloc(sizeof(STU));
h->next=g;
p=h;
while(p->next->next!=NULL)
{
for(s=p,q=p->next;q->next!=NULL;q=q->next)
{
if(flag == '1')
if(q->next->ID<s->next->ID)
s=q;
if(flag == '2')
if(q->next->chinese<s->next->chinese)
s=q;
if(flag == '3')
if(q->next->math<s->next->math)
s=q;
if(flag == '4')
if(q->next->english<s->next->english)
s=q;
if(flag == '5')
if(q->next->average<s->next->average)
s=q;
}
if(s!=q)
{
t=s->next;
s->next=t->next;
t->next=p->next;
p->next=t;
}
p=p->next;
}
g=h->next;
free(h);
return g;
}
STU *add_student(STU *stu_head)
{
STU *stu;
STU *head = stu_head;
STU *node = stu_head;
STU *node_fd;
int sel;
ASK_STU(stu);
stu->next = NULL;
printf("請輸入學生學號:");
scanf("%d", &stu->ID);
while(search_by_nb(node, stu->ID)){
printf("已經存在該學號!請重新輸入一個學號:");
scanf("%d", &stu->ID);
}
printf("請輸入學生名字:");
scanf("%s", stu->name);
printf("請輸入該學生英語成績:");
scanf("%f", &stu->english);
while(stu->english < 0.0 || stu->english > 100.0){
printf("輸入錯誤,請重新輸入英語成績:");
scanf("%f", &stu->english);
}
printf("請輸入該學生數學成績:");
scanf("%f", &stu->math);
while(stu->math < 0.0 || stu->math > 100.0){
printf("輸入錯誤,請重新輸入數學成績:");
scanf("%f", &stu->math);
}
printf("請輸入該學生語文成績:");
scanf("%f", &stu->chinese);
while(stu->chinese < 0.0 || stu->chinese > 100.0){
printf("輸入錯誤,請重新輸入數學成績:");
scanf("%f", &stu->chinese);
}
stu->all_sub = stu->chinese+stu->math+stu->english;
stu->average = stu->all_sub/3;
if(!head){
head = stu;
return head;
}
while(node->next)
node = node->next;
node->next = stu;
head = select_sort(head, '1');
return head;
}
STU *del_all(STU *stu_head)
{
if(!stu_head)
return NULL;
del_all(stu_head->next);
free(stu_head);
stu_head = NULL;
return NULL;
}
STU *del_one(STU *stu_head, int flag)
{
STU *node = stu_head;
STU *head = stu_head;
STU *pre;
char name[10];
unsigned long ID;
if(head = NULL){
printf("沒有任何學生信息!\n");
return head;
}
if(flag == '2'){
printf("請輸入要刪除的學生姓名:");
scanf("%s", name);
if(!strcmp(node->name, name)){
free(node);
head = node->next;
printf("成功刪除!按任意鍵返回。\n");
getch();
return head;
}
while(node){
if(!strcmp(node->name, name)){
pre->next = node->next;
free(node);
printf("成功刪除!按任意鍵返回。\n");
getch();
return head;
}
pre = node;
node = node->next;
}
printf("沒有找到該學生信息!\n");
return head;
}
if(flag == '3'){
printf("請輸入要刪除的學生學號:");
scanf("%d", &ID);
if(node->ID == ID){
free(node);
head = node->next;
printf("成功刪除!按任意鍵返回。\n");
getch();
return head;
}
while(node){
if(!strcmp(node->name, name)){
pre->next = node->next;
free(node);
printf("成功刪除!按任意鍵返回。\n");
getch();
return head;
}
pre = node;
node = node->next;
}
printf("沒有找到該學生信息!按任意鍵返回\n");
getch();
return head;
}
}
STU *del_student(STU *stu_head)
{
int sel;
STU *head = stu_head;
printf("1:刪除全部 2:按名字刪除3:按學號刪除0:返回\n");
printf("請選擇:\n");
sel = getch();
while(sel<'0'||sel>'3'){
printf("輸入錯誤,請重新選擇:\n");
sel = getch();
}
if(sel == '0')
return head;
if(!head){
printf("沒有任何學生信息!按任意鍵返回.\n");
getch();
return head;
}
if(sel == '1'){
head = del_all(head);
printf("刪除成功!按任意鍵返回.");
getch();
return head;
}
if(sel == '2'||sel =='3'){
head = del_one(head, sel);
return head;
}
}
void modify_student(STU *stu_head)
{
STU *head = stu_head;
STU *node_fd;
int sel;
char name[10];
unsigned long nb;
recyc3:
printf("1:修改指定學號的學生信息 2:修改指定姓名的學生信息 0:返回\n請選擇:\n");
sel = getch();
while(sel < '0'|| sel>'2'){
printf("輸入錯誤!請重新選擇:\n");
sel = getch();
}
if(sel == '1'||sel=='2'){
if(sel == '1'){
printf("請輸入要修改的學生學號:");
scanf("%d", &nb);
node_fd = search_by_nb(head, nb);
}
if(sel == '2'){
printf("請輸入要修改的學生姓名:");
scanf("%s", name);
node_fd = search_by_name(head, name);
}
if(node_fd){
printf("請輸入該學生英語成績:");
scanf("%f", &node_fd->english);
while(node_fd->english < 0.0 || node_fd->english > 100.0){
printf("輸入錯誤,請重新輸入英語成績:");
scanf("%f", &node_fd->english);
}
printf("請輸入該學生數學成績:");
scanf("%f", &node_fd->math);
while(node_fd->math < 0.0 || node_fd->math > 100.0){
printf("輸入錯誤,請重新輸入數學成績:");
scanf("%f", &node_fd->math);
}
printf("請輸入該學生語文成績:");
scanf("%f", &node_fd->chinese);
while(node_fd->chinese < 0.0 || node_fd->chinese > 100.0){
printf("輸入錯誤,請重新輸入數學成績:");
scanf("%f", &node_fd->chinese);
}
node_fd->all_sub = node_fd->chinese+node_fd->math+node_fd->english;
node_fd->average = node_fd->all_sub/3;
printf("修改成功!\n");
goto recyc3;
}
else{
printf("沒有該學生信息!\n");
goto recyc3;
}
}
}
STU *display_student(STU *stu_head)
{
int sel;
STU *head = stu_head;
STU *node = stu_head;
if(node == NULL){
printf("沒有任何學生信息,按任意鍵返回");
getch();
return head;
}
recyc:
printf("學號 姓名 語文 數學 英文 平均分 總分\n");
while(node){
printf("%d %s %0.1f %0.1f %0.1f %0.1f %0.1f\n", node->ID, node->name,\
node->chinese, node->math, node->english, node->average, node->all_sub);
node=node->next;
}
printf("排序方式: 1:按學號排序2:按語文成績排序3:按數學成績排序\n 4:按英文成績排序5:按總分排序0:返回\n請選擇:");
sel = getch();
while(sel < '0'|| sel>'5'){
printf("輸入錯誤!請重新選擇:");
sel = getch();
}
if(sel == '0')
return head;
head = node = select_sort(head, sel);
system("cls");
goto recyc;
return head;
}
STU *search_by_name(STU *stu_head, char name[])
{
STU *node = stu_head;
if(!node)
return NULL;
while(node){
if(!strcmp(node->name, name))
return node;
node=node->next;
}
return NULL;
}
STU *search_by_nb(STU *stu_head, unsigned long nb)
{
STU *node = stu_head;
if(!node)
return NULL;
while(node){
if(node->ID == nb)
return node;
node=node->next;
}
return NULL;
}
void search_student(STU *stu_head)
{
STU *head = stu_head;
STU *node;
int sel = 0;
char name[10];
unsigned long ID;
recyc2:
printf("1:按姓名查找2:按學號查找0:返回\n請選擇:");
sel = getch();
while(sel<'0' || sel>'2'){
printf("\n輸入錯誤,請重新選擇:");
sel = getch();
}
if(sel == '0')
return;
if(sel == '1'||sel=='2'){
if(sel == '1'){
printf("\n請輸入你要查找的學生姓名:");
scanf("%s", name);
node = search_by_name(head, name);
}
else{
printf("\n請輸入你要查找的學生學號:");
scanf("%d", &ID);
node = search_by_nb(head, ID);
}
if(node){
printf("學號 姓名 語文 數學 英文 平均分 總分\n");
printf("%d %s %0.1f %0.1f %0.1f %0.1f %0.1f\n", node->ID, node->name,\
node->chinese, node->math, node->english, node->average, node->all_sub);
goto recyc2;
}
else{
printf("沒有找到該學生信息!\n");
goto recyc2;
}
}
}</span><span style="font-size:18px;">
</span>
5.store.c
這個文件包含程序啟動時讀取文件內的學生成績信息,和需要保存時或者退出時向文件保存學生成績信息的操作。
<span style="font-size:16px;">#include <stdlib.h>
#include <stdio.h>
#include "students.h"
#define FILE_NAME "students"
void save_student(STU *stu_head)
{
STU *node = stu_head;
FILE *fp;
fp = fopen(FILE_NAME, "w+");
while(node){
fprintf(fp, "%ld %s %0.1f %0.1f %0.1f %0.1lf %0.1f\n", node->ID, node->name,\
node->chinese, node->math, node->english, node->all_sub, node->average);
node=node->next;
}
fclose(fp);
printf("保存成功!按任意鍵返回。\n");
getch();
}
STU *init_student(STU *stu_head)
{
STU *node = stu_head;
STU *head = stu_head;
STU *new_node;
int i;
FILE *fp;
char name[10];
int num;
ASK_STU(new_node);
new_node->next=NULL;
fp = fopen(FILE_NAME, "r+");
rewind(fp);
while((i = fscanf(fp, "%ld%s%f%f%f%lf%f\n", &new_node->ID, new_node->name,\
&new_node->chinese, &new_node->math, &new_node->english, &new_node->all_sub, &new_node->average)) == 7){
if(!head)
head = node = new_node;
else{
while(node->next)
node = node->next;
node->next = new_node;
}
ASK_STU(new_node);
new_node->next = NULL;
}
fclose(fp);
return head;
}</span>
四、總結
菜鳥修煉C語言基礎部分到此告一段落了,通過這段時間的修煉對C語言有了更加深入的理解,能夠熟練運用指針、數組、結構體和鏈表進行代碼的編寫了。如果以後有時間,可能會修煉一下C算法,下一段時間我會修煉C++。希望能對像我一樣的C語言菜鳥能提供到幫助,大家共同努力,共同奮斗!