1. 程式人生 > >文字檔案、二進位制檔案操作03(C)

文字檔案、二進位制檔案操作03(C)

現有一個二進位制檔案 E83_data.bin,檔案中包含了若干學生資訊, 請將檔案儲存至 C 盤根目錄下的 cdata 資料夾。其中學生資訊結構如下:
struct _student
{
char ID[15]; // 學號
char name[20]; // 姓名
int grade; // 年級
int scorces[3]; // 成績
}
 

編寫程式完成如下功能:
(1) 編寫一個函式,讀取二進位制檔案中的所有學生資訊。
(2) 編寫一個函式,輸出所有學生資訊,要求每個學生資訊佔一行,輸出格式要求:學號(佔 20 列,左對齊),姓名(佔 25 列,左對齊), 年級(佔 3 列,左對齊), 成績(每個成績佔 6 列,右對齊)。
(3) 編寫一個函式,對所有學生根據學生的平均成績按照從大到小排序。
(4) 編寫一個函式,將所有學生資訊輸出到 C 盤根目錄下的 cdata 資料夾中的文字檔案 E83_result.txt,要求每行輸出一個學生資訊,輸出格式要求如下:學號(佔 20 列,左對齊),姓名(佔 25 列,左對齊), 年級(佔 3 列,左對齊),成績(每個成績佔 6 列,右對齊),平均成績(佔 6 列,保留 2 為小數,右對齊)。
(5) 編寫一個函式,刪除所有學生中平均成績小於 score 的學生資訊,其中score 由引數傳入。
(6) 編寫測試程式。 其中要求刪除所有平均成績小於 40 分的學生資訊,並將剩下的學生資訊輸出到 C 盤根目錄下的 cdata 資料夾中的文字檔案E83_delresult.txt,要求每行輸出一個學生資訊,輸出格式要求如下: 學號(佔20 列,左對齊),姓名(佔 25 列,左對齊), 年級(佔 3 列,左對齊), 成績(每個成績佔 6 列,右對齊),平均成績(佔 6 列,保留 2 為小數,右對齊)
 

/*============================================================================================================================================
*學號:1527403059
*作業:E83
*功能:(1) 編寫一個函式,讀取二進位制檔案中的所有學生資訊。 
       (2) 編寫一個函式,輸出所有學生資訊,要求每個學生資訊佔一行,輸出格式要求:學號(佔 20 列,左對齊),姓名(佔 25 列,左對齊), 年級(佔 3 列,
           左對齊), 成績(每個成績佔 6 列,右對齊)。 
       (3) 編寫一個函式,對所有學生根據學生的平均成績按照從大到小排序。 
       (4) 編寫一個函式,將所有學生資訊輸出到 C 盤根目錄下的 cdata 資料夾中的文字檔案 E83_result.txt,要求每行輸出一個學生資訊,輸出格式要求如下:
           學號(佔 20 列,左對齊),姓名(佔 25 列,左對齊), 年級(佔 3 列,左對齊), 成績(每個成績佔 6 列,右對齊),平均成績(佔 6 列,保留 2 為小數,
		   右對齊)。 
       (5) 編寫一個函式,刪除所有學生中平均成績小於 score 的學生資訊,其中score 由引數傳入。 
       (6) 編寫測試程式。其中要求刪除所有平均成績小於 40 分的學生資訊,並將剩下的學生資訊輸出到 C 盤根目錄下的 cdata 資料夾中的文字檔案
           E83_delresult.txt,要求每行輸出一個學生資訊,輸出格式要求如下:學號(佔20 列,左對齊),姓名(佔 25 列,左對齊), 年級(佔 3 列,左對齊), 
		   成績(每個成績佔 6 列,右對齊),平均成績(佔 6 列,保留 2 為小數,右對齊)。 
*作者:陸胤任
*日期:2016.1.3
*===============================================================================================================================================*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct student                                     //結構體
{
	char ID[15];
	char name[20];
	int grade;
	int scorces[3];
};

struct StudentNode                                  //連結串列
{
	struct student data;
	double aver;
	struct StudentNode *next;
};

/*function define
*@brief:讀取檔案中的所有資訊
*@param:char *FileName:檔名
*@reval:*head:連結串列頭節點
*/
struct StudentNode *CreateListFromFile(char *FileName)
{
	FILE *fp;
	struct StudentNode *head,*p,*q;
	struct student t;
	int res;
	fp=fopen(FileName,"rb");                                               //檢查是否開啟檔案失敗
	if(fp==NULL)
	{
		printf("無法開啟檔案!\n");
		exit(0);
	}
	head=(struct StudentNode *)malloc(sizeof(struct StudentNode));        //開闢新空間
	q=head;
	while(!feof(fp))                                                     //如果未遇到檔案結束標誌
	{
		res=fread(&t,sizeof(struct student),1,fp);
		if(res==0)
		{
			continue;
		}
		p=(struct StudentNode *)malloc(sizeof(struct StudentNode));
		p->data=t;
		p->aver=(p->data.scorces[0]+p->data.scorces[1]+p->data.scorces[2])/3.0;    //求平均分
		q->next=p;
		q=p;
	}
	p->next=NULL;
	fclose(fp);                                                     //關閉檔案
	return head;
}

/*function define
*@brief:顯示檔案內容到螢幕上
*@param:struct StudentNode *Head:連結串列頭節點
*@reval:void
*/
void DisplayList(struct StudentNode *Head)
{
	struct StudentNode *p;
	p=Head->next;
	while(p!=NULL)                                                  //輸出內容
	{
		printf("%-20s%-25s%-3d%6d%6d%6d%6.2lf\n",p->data.ID,p->data.name,p->data.grade,p->data.scorces[0],p->data.scorces[1],p->data.scorces[2],p->aver);
		p=p->next;
	}
	printf("\n");
}

/*function define
*@brief:對資料進行排序
*@param:struct StudentNode *Head:連結串列頭節點
*@reval:void
*/
void SortList(struct StudentNode *Head)
{
	struct StudentNode *pi,*pj,*pmax;
	struct student temp;
	double aver;
	pi=Head->next;
	while(pi->next!=NULL)                                 //選擇排序法
	{
		pmax=pi;
		pj=pi->next;
		while(pj!=NULL)
		{
			if(pmax->aver<pj->aver)
			{
				pmax=pj;
			}
			pj=pj->next;
		}
		if(pmax!=pi)
		{
			temp=pmax->data;
			aver=pmax->aver;

			pmax->data=pi->data;
			pmax->aver=pi->aver;

			pi->data=temp;
			pi->aver=aver;
		}
		pi=pi->next;
	}
}

/*function define
*@brief:刪除節點
*@param:struct StudentNode *Head:連結串列頭節點
        double Score:引數傳遞的分數
*@reval:void
*/
void DeleteNode(struct StudentNode *Head,double Score)
{
	struct StudentNode *p,*q;
	q=Head;
	p=Head->next;
	while(p!=NULL)
	{
		if(p->aver<=Score)
		{
			q->next=p->next;
			free(p);
			p=q->next;
		}
		else
		{
			q=p;
			p=p->next;
		}
	}
}

/*function define
*@brief:將檔案內容儲存在指定檔案中
*@param:char *FileName:檔名
        struct StudentNode *Head:連結串列頭節點
*@reval:void
*/
void WriteInfoToFile(char *FileName,struct StudentNode *Head)
{
	FILE *fp;
	struct StudentNode *p;
	fp=fopen(FileName,"w");
	if(fp==NULL)
	{
		printf("開啟檔案失敗!\n");
		exit(0);
	}
	p=Head->next;
	while(p!=NULL)
	{
		fprintf(fp,"%-20s%-25s%-3d%6d%6d%6d%6.2lf\n",p->data.ID,p->data.name,p->data.grade,p->data.scorces[0],p->data.scorces[1],p->data.scorces[2],p->aver);
		p=p->next;
	}
	fprintf(fp,"\n");                           //格式化輸出換行符
	fclose(fp);
}

/*function define
*@brief:釋放節點
*@param:struct StudentNode *Head:連結串列頭節點
*@reval:void
*/
void free_node(struct StudentNode *head)
{
	struct StudentNode *p,*q;
	p=head;
	while(NULL!=p)
	{
		q=p;
		p=p->next;
		free(q);
	}
}

int main()                                                  //主函式
{
	struct StudentNode *head;
	head=CreateListFromFile("C:\\cdata\\E83_data.bin");
	printf("檔案讀取完成後學生資訊如下:\n");
	DisplayList(head);
	SortList(head);
	printf("排序後學生的資訊如下:\n");
	DisplayList(head);
	WriteInfoToFile("C:\\cdata\\E83_result.txt",head);
	DeleteNode(head,40.0);
	WriteInfoToFile("C:\\cdata\\E83_delresult.txt",head);
	free_node(head);                                         //釋放節點
	return 0;
}