1. 程式人生 > >學生成績管理系統(C語言實現)

學生成績管理系統(C語言實現)

        今天,我來介紹一個C語言的小專案 --- 學生成績管理系統。在該系統中,主要是完成對學生資訊的錄入,新增,刪除,修改,查詢以及按照要求完成學生資訊的排序,此外還包括系統的初始化和清空。

       整個專案包括三個檔案main.c  ,   Sort.h  , 以及Sort.c。在main.c中,主要是主選單的初始化以及對於學生成績管理系統的各種操作。在Sort.h中主要是巨集定義,列舉型別,以及一些函式的宣告,為了在另外兩個.c檔案中進行使用。而在Sort.h中則是每項操作下所對應的具體操作和功能程式碼實現。

程式部分截圖:

具體如下:

main.c的實現是較為容易的,包含了自定義庫檔案Sort.h,通過獲取輸入選擇執行相關的操作

#define _CRT_SECURE_NO_WARNINGS
#include"Sort.h"
//自定義一個歡迎介面
void WelcomeMenu()
{
	printf("*********************************\n");
	printf("****                        *****\n");
	printf("****歡迎進入學生成績管理系統*****\n");
	printf("****                        *****\n");
	printf("****                        *****\n");
	printf("****              --子陵製作*****\n");
	printf("*********************************\n");
	printf("\a");
}
//主選單介面
void MainMenu()
{
	printf("*******************************\n");
	printf("******  學生成績管理系統 ******\n");
	printf("****** 1,add    2,del    ******\n");
	printf("****** 3,modify 4,search ******\n");
	printf("****** 5,sort   6,show   ******\n");
	printf("****** 7,clear  8,exit   ******\n");
	printf("*******************************\n");
}

int main()
{
	int input = 0;
	struct Message mes;
	InitStu(&mes);
	WelcomeMenu();
	system("pause");
	system("cls");
	do
	{
		MainMenu();
		printf("請輸入您的選擇:");
		scanf("%d", &input);
		switch(input)
		{
		case ADD:
			AddMessage(&mes);
			break;
		case DEL:
			DelMessage(&mes);
			break;
		case MODIFY:
			ModifyMessage(&mes);
			break;
		case SEARCH:
			SearchMessage(&mes);
			break;
		case SORT:
			SortMessage(&mes);
			break;
		case SHOW:
			ShowMessage(&mes);
			break;
		case CLEAR:
			ClearMessage(&mes);
			break;
		}
	}while(input);
	
	system("pause");
	return 0;
}

 Sort.h中包含了巨集定義,列舉,結構體以及函式宣告等

#include<stdio.h>
#include<Windows.h>
#define MAX_SIZE 100
#define MAX_NAME 100
#define SEX_MAX 2
#define MAX_DEPT 20
#define MAX_SNU 200
#define MAX_FIELD 20
//主選單介面的選項
enum Option
{
	EMPTY,
	ADD,
	DEL,
	MODIFY,
	SEARCH,
	SORT,
	SHOW,
	CLEAR
};
//所要修改的資訊
enum Modify_Option
{
	NO,
	MODIFY_NAME,
	MODIFY_AGE,
	MODIFY_SNUMBER,
	MODIFY_SCORE
};
//科目資訊
enum SubjectType
{
	EXIT,
	MATH,
	ENGLISH,
	PHYSICAL
};
typedef struct Student
{
	char name[MAX_NAME]; //姓名
	int age;             //年齡
	int sNumber;         //學號
	float math;          //高數成績
	float English;       //英語成績
	float Physical;      //物理成績
	float TotalScore;    //成績總分
	float AverageScore;  //平均分
}Student;
//學生資訊
typedef struct Message
{
	struct Student stu[MAX_SIZE];  //定義一個學生陣列
	int size;
}Message, *pMessage;
void InitStu(pMessage mes);//初始化學生資訊
void AddMessage(pMessage mes);//新增學生資訊
void DelMessage(pMessage mes);//刪除學生資訊
void ShowMessage(pMessage mes);//檢視學生資訊
void SearchMessage(pMessage mes);//查詢學生資訊
void ModifyMessage(pMessage mes);//修改學生資訊
void SortMessage(pMessage mes);//按要求對學生排序
void ClearMessage(pMessage mes);//清空學生資訊

 Sort.h是最重要的。在這一部分遇到的一個小問題折磨了很久。我們都知道,陣列名相當於首元素的地址,所以對於獲取姓名的時候,並不需要加&操作符,但對諸如年齡,成績等,則是需要加上&操作符。剛開始的時候忘了加&操作符,導致程式好幾次不能夠成功,後來仔細看了一下,才找到這個問題(刻骨銘心)。此外,在排序的過程中,用到了兩種排序:氣泡排序和希爾排序,希爾排序掌握的還是不太熟練。

#define _CRT_SECURE_NO_WARNINGS
#include"Sort.h"
#include<string.h>
//初始化學生資訊
void InitStu(pMessage mes)
{
	mes->size = 0;       //學生個數為0
	memset(mes->stu, 0, sizeof(mes->stu));  //學生所有資訊均為0
}
//在編寫該函式的過程中,遇到的問題,由於對諸如姓名,性別,專業等的資訊的儲存,
//是用字元陣列進行儲存的,故此,在資訊儲存的時候,陣列名相當於陣列首元素的地址,不需要進行&操作
//但是值得注意的是age是int型別的,需要採用&操作

//新增學生資訊
void AddMessage(pMessage mes)
{
	int i = 0;
	//判斷當前學生個數已達上限,如果空間已滿,則不再存入
	if(mes->size >= MAX_SIZE)
	{
		printf("儲存資訊達到最大,無法進行資訊新增\n");
		return;
	}
	printf("請輸入姓名:");
	scanf("%s", mes->stu[mes->size].name);
	printf("請輸入年齡:");
	scanf("%d", &mes->stu[mes->size].age);
	printf("請輸入學號:");
	scanf("%d", &mes->stu[mes->size].sNumber);
	printf("請輸入高數的成績:");
	scanf("%f", &mes->stu[mes->size].math);
	printf("請輸入英語的成績:");
	scanf("%f", &mes->stu[mes->size].English);
	printf("請輸入大物的成績:");
	scanf("%f", &mes->stu[mes->size].Physical);
	//每錄入一個學生資訊,mes->size加1
	mes->size++;
}

//查詢學生資訊
int FindMessage(pMessage mes, char name[])
{
	int i = 0;
	//遍歷學生資訊,與傳入的姓名進行比較,找到則返回1,如果找不到則返回0
	//字串比較,使用strcmp
	for(i=0; i<mes->size; i++)
	{
		if(strcmp(name, mes->stu[i].name) == 0)
		{
			return i;
		}
	}
	return -1;
}
//刪除學生資訊
void DelMessage(pMessage mes)
{
	char name[MAX_NAME] = {0};
	int pos = 0 ;
	int i = 0;
	//如果當前空間為空,則不再進行刪除操作
	if(mes->size <= 0)
	{
		printf("資訊已經為空,無法進行刪除\n");
		return;
	}
	//對於要刪除的學生,先要找到該學生,然後再進行刪除
	printf("請輸入您要刪除的學生的姓名:");
	scanf("%s", name);
	pos = FindMessage(mes, name);
	//當前系統中沒有該學生
	if(pos == -1)
	{
		printf("該學生不存在,無法進行刪除\n");
		return;
	}
	for(pos=i+1; pos<mes->size; pos++)
	{
		mes->stu[pos] = mes->stu[pos+1];
	}
	mes->size--;
	printf("該學生資訊已被刪除\n");
}
//定義全域性變數sum(總分)
float sum = 0;
//在這個函式中犯的錯誤與AddMessage中遇到的問題類似,即年齡的輸出需採用%d的形式


//顯示學生資訊
void ShowMessage(pMessage mes)
{
	int i = 0;
	printf("%10s\t%5s\t%10s\t%15s\t%15s\t%15s\t%15s\t%15s\n", "姓名", "年齡", "學號", "高數","英語","大物", "總分", "平均分");
	for(i=0; i<mes->size; i++)
	{
		sum = mes->stu[i].math+mes->stu[i].English+mes->stu[i].Physical;
		printf("%10s\t%5d\t%10d\t%15.2f\t%15.2f\t%15.2f\t%15.2f\t%15.2f\n", 
			mes->stu[i].name, mes->stu[i].age, mes->stu[i].sNumber, mes->stu[i].math, mes->stu[i].English, mes->stu[i].Physical, sum, sum/3);
	}
}
//查詢學生資訊
void SearchMessage(pMessage mes)
{
	int pos = 0;
	char name[MAX_SIZE] = {0};
	printf("請輸入您要查詢的學生的姓名:");
	scanf("%s", name);
	pos = FindMessage(mes, name);
	if(pos == -1)
	{
		printf("您所查詢的學生不存在\n");
		return;
	}else
	{
		printf("%10s\t%5s\t%10s\t%15s\t%15s\t%15s\t%15s\t%15s\n", "姓名", "年齡", "學號", "高數","英語","大物", "總分", "平均分");
		sum = mes->stu[pos].math+mes->stu[pos].English+mes->stu[pos].Physical;
		printf("%10s\t%5d\t%10d\t%15.2f\t%15.2f\t%15.2f\t%15.2f\t%15.2f\n", 
			mes->stu[pos].name, mes->stu[pos].age, mes->stu[pos].sNumber, mes->stu[pos].math, mes->stu[pos].English, mes->stu[pos].Physical, sum, sum/3);
	}
}
//修改選單
void MyMenu()
{
	printf("*********************************\n");
	printf("*****1,修改姓名   2,修改年齡*****\n");
	printf("*****      3,修改學號       *****\n");
	printf("*****      4,修改成績       *****\n");
	printf("*********************************\n");
}
//修改科目選單
void SubjectMenu()
{
	printf("*********************************\n");
	printf("*****    1, 修改高數成績    *****\n");
	printf("*****    2,修改英語成績    *****\n");
	printf("*****    3,修改大物成績    *****\n");
	printf("*********************************\n");
}
//修改學生資訊
void ModifyMessage(pMessage mes)
{
	int k = 0;
	int i = 0;
	int j = 0;
	char name[MAX_SIZE] =  {0};
	int input = 0;
	int inputSub = 0;
	int pos = 0;
	printf("請輸入您要修改的學生名字:");
	scanf("%s", name);
	pos = FindMessage(mes, name);
	//判斷要修改的學生是否存在
	if(pos == -1)
	{
		printf("您所要修改的學生不存在\n");
		return;
	}else
	{
		MyMenu();
		printf("請輸入您要修改的型別:");
		scanf("%d", &input);
		switch(input)
		{
		case MODIFY_NAME:
			printf("請輸入新的名字:");
			scanf("%s", mes->stu[pos].name);
			break;
		case MODIFY_AGE:
			printf("請輸入新的年齡:");
			scanf("%d", &mes->stu[pos].age);
			break;
		case MODIFY_SNUMBER:
			printf("請輸入新的學號:");
			scanf("%d", &mes->stu[pos].sNumber);
			break;
		case MODIFY_SCORE:
			SubjectMenu();
			printf("請輸入您要修改的科目:");
			scanf("%d", &inputSub);
			switch(inputSub)
			{
			case 1:
				printf("請輸入新的高數成績:");
				scanf("%f", &mes->stu[pos].math);
				break;
			case 2:
				printf("請輸入新的英語成績:");
				scanf("%f", &mes->stu[pos].English);
				break;
			case 3:
				printf("請輸入新的大物成績:");
				scanf("%f", &mes->stu[pos].Physical);
				break;
			}
			
		}
		printf("%10s\t%5s\t%10s\t%15s\t%15s\t%15s\t%15s\t%15s\n", "姓名", "年齡", "學號", "高數","英語","大物", "總分", "平均分");
		sum = mes->stu[pos].math+mes->stu[pos].English+mes->stu[pos].Physical;
		printf("%10s\t%5d\t%10d\t%15.2f\t%15.2f\t%15.2f\t%15.2f\t%15.2f\n", 
			mes->stu[pos].name, mes->stu[pos].age, mes->stu[pos].sNumber, mes->stu[pos].math, mes->stu[pos].English, mes->stu[pos].Physical, sum, sum/3);
	
	}
}
//按指定要求對學生資訊排序
void SortMenu()
{
	printf("********************************\n");
	printf("****      1,按姓名排序     *****\n");
	printf("****      2,按年齡排序     *****\n");
	printf("****      3,按學號排序     *****\n");
	printf("****      4,按總分排序     *****\n");
	printf("********************************\n");
}
//按姓名排序(使用氣泡排序實現)
static void SortName(pMessage mes)
{
	int i, j;
	int flag;
	for(i=0; i<mes->size; i++)
	{
		flag = 1;
		for(j=0; j<mes->size-1-i; j++)
		{
			if(strcmp(mes->stu[j].name, mes->stu[j+1].name) > 0)
			{
				Student tmp = mes->stu[j];
				mes->stu[j] = mes->stu[j+1];
				mes->stu[j+1] = tmp;
				flag = 0;
			}
		}
		if(flag == 1)
		{
			break;
		}
	}
}
//按年齡進行排序(希爾排序實現)
static void SortAge(pMessage mes)
{
	int i, j, g;
	int key;
	int gap = mes->size;
	while(1)
	{
		gap = gap/3+1;
		for(g=0; g<gap; g++)
		{
			for(i=g+gap; i<mes->size; i++)
			{
				key = mes->stu[i].age;
				for(j=i-gap; j>=0; j-=gap)
				{
					if(key < mes->stu[j].age)
					{
						mes->stu[j+gap] = mes->stu[j];
					}else
					{
						break;
					}
				}
				mes->stu[j+gap].age= key;
			}
		}
		if(gap == 1)
		{
			break;
		}
	}
}
//按學號排序(氣泡排序實現)
static void SortSNo(pMessage mes)
{
	int i, j;
	int flag;
	for(i=0; i<mes->size; i++)
	{
		flag = 1;
		for(j=0; j<mes->size-1-i; j++)
		{
			if(mes->stu[j].sNumber > mes->stu[j+1].sNumber)
			{
				Student tmp = mes->stu[j];
				mes->stu[j] = mes->stu[j+1];
				mes->stu[j+1] = tmp;
				flag = 0;
			}
		}
		if(flag == 1)
		{
			break;
		}
	}
}
//按總分排序(氣泡排序實現)
static void SortTotalScore(pMessage mes)
{
	int i, j;
	int flag;
	for(i=0; i<mes->size; i++)
	{
		flag = 1;
		sum = mes->stu[i].math+mes->stu[i].English+mes->stu[i].Physical;
		mes->stu[i].TotalScore = sum;
		for(j=0; j<mes->size-1-i; j++)
		{
			if(mes->stu[j].TotalScore > mes->stu[j+1].TotalScore)
			{
				Student tmp = mes->stu[j];
				mes->stu[j] = mes->stu[j+1];
				mes->stu[j+1] = tmp;
				flag = 0;
			}
		}
		if(flag == 1)
		{
			break;
		}
	}
}
//選擇要排序的方法
void SortMessage(pMessage mes)
{
	int input = 0;
	SortMenu();
	printf("請選擇您要排序的方式:");
	scanf("%d", &input);
	switch(input)
	{
	case 1:
		SortName(mes);
		ShowMessage(mes);
		break;
	case 2:
		SortAge(mes);
		ShowMessage(mes);
		break;
	case 3:
		SortSNo(mes);
		ShowMessage(mes);
		break;
	case 4:
		SortTotalScore(mes);
		ShowMessage(mes);
		break;
	}
}
//清空學生資訊系統
void ClearMessage(pMessage mes)
{
	mes->size = 0;
	memset(mes->stu, 0, sizeof(mes->stu));
	printf("該系統已被清空\n");
}

總體來說,這個小專案讓我收穫還是挺大的