欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言實現(xiàn)學(xué)生成績管理系統(tǒng)實戰(zhàn)教學(xué)

 更新時間:2019年01月17日 08:38:47   投稿:laozhang  
在本篇文章里小編給大家分享了關(guān)于C語言實現(xiàn)學(xué)生成績管理系統(tǒng)實戰(zhàn)教學(xué)內(nèi)容,有興趣的朋友們可以跟著學(xué)習(xí)參考下。

趁著放假無事,開始用C語言開發(fā)一些小的項目,鞏固基礎(chǔ)知識的同時學(xué)習(xí)新的知識。

學(xué)生成績管理系統(tǒng)實現(xiàn)的功能有:成績錄入、學(xué)生成績查詢、刪除、修改、通過文件保存等。

開發(fā)這樣一個系統(tǒng)需要具備的知識:線性表(鏈表)、文件操作、排序(如果需要成績排序)。

開發(fā)環(huán)境為VS2015;在Linux下沒有conio.h的頭文件,需要修改與getch()函數(shù)相關(guān)的代碼。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
 
/*學(xué)生信息結(jié)構(gòu)體*/
typedef struct Node
{
	char Name[10];		//學(xué)生姓名
	char ID[15];		//學(xué)生學(xué)號
	int Score[3];	//三科成績(數(shù)學(xué)、英語、數(shù)據(jù)結(jié)構(gòu))
	float Ave_Sco;
	struct Node *next;
}Lnode;
 
void Display();  /*界面顯示函數(shù)*/
void GetScore(Lnode *&h); /*成績錄入函數(shù)*/
void PrintScore(Lnode *h); /*成績打印函數(shù)*/
void ModifyScore(Lnode *h); /*成績修改函數(shù)*/
void FindInf(Lnode *h);  /*查找信息*/
void Delete(Lnode *h);  /*刪除函數(shù)*/
void Quit(Lnode *h);  /*退出函數(shù)*/
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;  //使頭節(jié)點指針域為空
}
 
int main()
{
	Lnode *ScoreList;  //建立成績鏈表,所有學(xué)生信息存放在此鏈表
	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("是否繼續(xù)輸入 (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結(jié)束
	}
	
	return 0;
}
 
/*系統(tǒng)界面顯示*/
void Display()
{
	printf("\t\t**********************************************\n");
	printf("\t\t*************歡迎使用成績管理系統(tǒng)*************\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、查找學(xué)生信息\n");
	printf("\t\t\t\t5、刪除學(xué)生信息\n");
	printf("\t\t\t\t6、退出系統(tǒng)\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));		//為學(xué)生信息申請節(jié)點
	printf("請依次輸入學(xué)生信息:\n");
	printf("姓名 學(xué)號 數(shù)學(xué) 英語 數(shù)據(jù)結(jié)構(gòu)\n");
	scanf("%s %s %d %d %d", &name, &id, &Math, &English, &Datastruct);
 
	for (; q->next != NULL; q = q->next){;}  //移動到尾節(jié)點
	
	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","排名", "學(xué)號", "姓名", "數(shù)學(xué)", "英語", "數(shù)據(jù)結(jié)構(gòu)", "平均績點");
	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("請輸入學(xué)生姓名:");
	scanf("%s", name);
	printf("請輸入學(xué)生學(xué)號:");
	scanf("%s", id);
 
	while (p)
	{
		if (strcmp(p->Name, name)==0 && strcmp(p->ID, id)==0)
		{
			printf("當(dāng)前學(xué)生信息:\n");
			printf("%-14s%-8s%-8s%-8s%-8s\n", "學(xué)號", "姓名", "數(shù)學(xué)", "英語", "數(shù)據(jù)結(jié)構(gòu)");
			printf("%-14s%-8s%-8d%-8d%-8d\n", p->ID, p->Name, p->Score[0], p->Score[1], p->Score[2]);
			printf("請輸入更正后的數(shù)學(xué)成績:");
			scanf("%d", &Math);
			printf("請輸入更正后的英語成績:");
			scanf("%d", &English);
			printf("請輸入更正后的數(shù)據(jù)結(jié)構(gòu)成績:");
			scanf("%d", &Datastruct);
			p->Score[0] = Math;
			p->Score[1] = English;
			p->Score[2] = Datastruct;
			break;
		}
		else
		{
			p = p->next;
		}
	}//while循環(huán)結(jié)束
}
 
/*信息查找*/
void FindInf(Lnode *h)
{
	Lnode *p = h->next;
	char name[10], id[15];
	printf("請輸入學(xué)生姓名:");
	scanf("%s", name);
	printf("請輸入學(xué)生學(xué)號:");
	scanf("%s", id);
 
	while (p)
	{
		if (strcmp(p->Name, name) == 0 && strcmp(p->ID, id) == 0)
		{
			printf("當(dāng)前學(xué)生信息:\n");
			printf("%-14s%-8s%-8s%-8s%-8s\n", "學(xué)號", "姓名", "數(shù)學(xué)", "英語", "數(shù)據(jù)結(jié)構(gòu)");
			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循環(huán)結(jié)束
}
 
/*刪除*/
void Delete(Lnode *h)
{
	Lnode *p = h, *q;
	q = p->next;
	char name[10], id[15];
	printf("請輸入學(xué)生姓名:");
	scanf("%s", name);
	printf("請輸入學(xué)生學(xué)號:");
	scanf("%s", id);
 
	while (q)
	{
		if (strcmp(q->Name, name) == 0 && strcmp(q->ID, id) == 0)
		{
			p->next = q->next;
			free(q);  //刪除p節(jié)點		
			printf("刪除成功\n");
			break;
		}
		else
		{
			p = p->next;
			q = q->next;
		}
	}//while循環(huán)結(jié)束
}
 
/*退出系統(tǒng)*/
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判斷文件是否為結(jié)束要注意的問題:
			當(dāng)讀取文件結(jié)束時,feof函數(shù)不會立即設(shè)置標(biāo)志符為-1,而是
			需要再讀取一次后,才會設(shè)置。所以要先讀一次。
	*/
	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循環(huán)結(jié)束
 
	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的內(nèi)容寫到文件中
		if (flag != 1)
		{
			break;
		}
		p = p->next;
	}
	fclose(file);
}

雖然是很簡單的小項目,還是有很多問題。

一:鏈表相關(guān)

在寫成績錄入和成績打印功能時,發(fā)現(xiàn)始終只能保存(沒加入文件保存)最后一個數(shù)據(jù),確定鏈表的相關(guān)操作沒有問題,仔細(xì)判斷邏輯關(guān)系后,發(fā)現(xiàn)是每次在頭節(jié)點傳到GetScore()函數(shù),為新節(jié)點申請內(nèi)存后,直接將數(shù)據(jù)保存在了新申請的節(jié)點里面,沒有將鏈表移動到尾節(jié)點,導(dǎo)致每次錄入成績,都會覆蓋前一次輸入的數(shù)據(jù)。解決辦法是鏈表傳到函數(shù)后,先移動到最后一個節(jié)點,將新申請的節(jié)點掛接在最后一個節(jié)點之后。

/*成績錄入*/
void GetScore(Lnode *&h)
{
	Lnode *p, *q = h;
	char name[10], id[15];
	int Math, English, Datastruct;
	p = (Lnode *)malloc(sizeof(Lnode));		//為學(xué)生信息申請節(jié)點
	printf("請依次輸入學(xué)生信息:\n");
	printf("姓名 學(xué)號 數(shù)學(xué) 英語 數(shù)據(jù)結(jié)構(gòu)\n");
	scanf("%s %s %d %d %d", &name, &id, &Math, &English, &Datastruct);
 
	for (; q->next != NULL; q = q->next){;}  //移動到尾節(jié)點
	//保存數(shù)據(jù)
	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;
        //始終指向最后一個節(jié)點
	p->next = NULL;
	q->next = p;
	q = p;
}

二、文件操作

用文件保存遇到的問題主要是每次打印數(shù)據(jù)時除正常數(shù)據(jù)外,始終多一行亂碼。判斷方法是while(!feof(file))。排除錯誤時確定了兩種可能性:多保存了一行;多讀取了一行。經(jīng)過某度feof()與EOF的關(guān)系后,確定是多讀取了一行數(shù)據(jù)。

用feof()函數(shù)進(jìn)行文件尾判斷時,當(dāng)文件已經(jīng)到達(dá)尾部后,還需要在讀取一次后,feof()函數(shù)才會返回-1,所以會出現(xiàn)多讀一次的情況;解決辦法時,在循環(huán)讀取之前先將第一個數(shù)據(jù)讀取出來,然后在正常讀取。即注意多讀一次的問題。

/*打開文件*/
void LoadInf(Lnode *h)
{
	Lnode *p = h;
	Lnode *q;  //臨時變量 用于保存從文件中讀取的信息
	FILE* file = fopen("./Information.dat", "rb");
	if (!file)
	{
		printf("文件打開失??!");
		return ;
	}
 
	/*
		使用feof判斷文件是否為結(jié)束要注意的問題:
			當(dāng)讀取文件結(jié)束時,feof函數(shù)不會立即設(shè)置標(biāo)志符為-1,而是
			需要再讀取一次后,才會設(shè)置。所以要先讀一次。
	*/
	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循環(huán)結(jié)束
	p->next = NULL;
	fclose(file);
}

相關(guān)文章

  • c語言中位字段與結(jié)構(gòu)聯(lián)合的組合使用詳解

    c語言中位字段與結(jié)構(gòu)聯(lián)合的組合使用詳解

    本篇文章是對c語言中位字段與結(jié)構(gòu)聯(lián)合的組合使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • 淺談C語言的變量和常量

    淺談C語言的變量和常量

    這篇文章主要為大家詳細(xì)介紹了C語言的變量和常量,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • 使用?c++?在?windows?上定時執(zhí)行一個函數(shù)的示例代碼

    使用?c++?在?windows?上定時執(zhí)行一個函數(shù)的示例代碼

    這篇文章主要介紹了使用c++在windows上穩(wěn)定定時執(zhí)行一個函數(shù),本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-07-07
  • C語言?超詳細(xì)介紹與實現(xiàn)線性表中的無頭單向非循環(huán)鏈表

    C語言?超詳細(xì)介紹與實現(xiàn)線性表中的無頭單向非循環(huán)鏈表

    無頭單向非循環(huán)鏈表:結(jié)構(gòu)簡單,一般不會單獨用來存數(shù)據(jù)。實際中更多是作為其他數(shù)據(jù)結(jié)構(gòu)的子結(jié)構(gòu),如哈希桶、圖的鄰接表等等。另外這種結(jié)構(gòu)在筆試面試中出現(xiàn)很多
    2022-03-03
  • C語言魔塔游戲的實現(xiàn)代碼

    C語言魔塔游戲的實現(xiàn)代碼

    這篇文章主要介紹了C語言魔塔游戲的實現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • VSCode配置C/C++并添加非工作區(qū)頭文件的方法

    VSCode配置C/C++并添加非工作區(qū)頭文件的方法

    這篇文章主要介紹了VSCode配置C/C++并添加非工作區(qū)頭文件的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-03-03
  • C++中的const限定符的使用和作用

    C++中的const限定符的使用和作用

    C++ 中的 const 限定符用于聲明不可變量,即在變量聲明時指定該變量的值不可修改。它的使用可以幫助程序員避免一些常見的編程錯誤,如誤修改不應(yīng)該被修改的變量的值等
    2023-05-05
  • C語言版猜數(shù)字小游戲

    C語言版猜數(shù)字小游戲

    這篇文章主要為大家詳細(xì)介紹了C語言版猜數(shù)字小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • C語言超詳細(xì)講解函數(shù)指針的運(yùn)用

    C語言超詳細(xì)講解函數(shù)指針的運(yùn)用

    函數(shù)指針是一個指針變量,它可以存儲函數(shù)的地址,然后使用函數(shù)指針,下面這篇文章主要給大家介紹了關(guān)于C語言進(jìn)階教程之函數(shù)指針的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • C語言中的逗號運(yùn)算符詳解

    C語言中的逗號運(yùn)算符詳解

    在C語言中逗號“,”也是一種運(yùn)算符,稱為逗號運(yùn)算符,其功能是把兩個表達(dá)式連接起來組成一個表達(dá)式,?稱為逗號表達(dá)式,這篇文章主要介紹了C語言中的逗號運(yùn)算符,需要的朋友可以參考下
    2022-11-11

最新評論