實驗內容:
從檔案中讀取學生資訊并列印,完成以下編程實驗,除錯運行程式并完成報告,
設每個學生包含如下資訊:
屬性名
姓名
專業名稱
英語成績
線性代數成績
C成績
總成績
型別
字串
字串
整數
整數
整數
整數(初始化為0)
- 設計一個表示學生資訊的結構體 struct student;
- 撰寫函式從檔案讀入所有學生資訊:
- 函式定義 int ReadStudentInfo(const char* filename, struct student** pStudents); 函式回傳值:回傳學生個數,失敗回傳-1,輸入引數const char* filename:資料檔案名;struct student** pStudents:回傳讀取的學生資訊,記憶體由ReadStudentInfo函式分配,main函式釋放,
- 建議函式流程:
- 打開資料檔案,失敗回傳-1;
- 從頭到尾掃描資料檔案(即預讀一遍)獲得學生人數;
- 根據學生人數,利用malloc和sizeof等函式或運算子為struct student** pStudents分配記憶體;
- 利用fseek函式,定位到檔案頭;
- 讀取資料檔案,并把每一條記錄通過陣列下標法或指標法保存到結構體陣列pStudents中;
- 關閉檔案;
- 回傳學生人數,
- 資料檔案格式說明:
一行一條學生資訊的記錄,不同屬性用空格隔開,輸入資料中無總成績記錄,例如:
張三 通信 89 93 95
李四 網路 88 91 94
王五 物聯網 71 94 88
…
- 撰寫統計函式:
- 函式定義void Count(struct student pStudents[], int num),輸入引數分別為保存學生的結構體陣列和學生人數,
- 功能為:統計所有學生的總成績和每個專業(假定一共三個專業:通信,網路,物聯網)的平均成績;輸入引數包括學生資訊結構體陣列,學生人數,回傳的每個學生的總成績直接填充到對應的輸入結構體陣列對應欄位中,統計資訊包括三個專業的總人數、平均成績陣列,用全域變數來表示,訪問每個學生資訊的時候,用指標來指向當前正在處理的學生,
- 設計一個或者三個帶引數的宏,判斷輸入的字串是否是指定的專業名稱,并在函式Count中使用,
- 撰寫資訊輸出函式:
要求通過一定的格式控制符,使得輸出美觀,輸出格式為:
學生資訊:
-----------------------------------------------------
序號 姓 名 專業名稱 英語成績 線性代數成績 C成績 總成績
1 張三 通信 89 93 95 277
2 … …
統計資訊:
-----------------------------------------------------
序號 專業名稱 學生人數 平均成績
1 通信 322 242
2 … …
- 撰寫main函式實作:
- 定義變數,其中保存學生資訊的資料檔案直接在源代碼中初始化;
- 讀取學生資訊,如果失敗,列印失敗資訊并退出程式;
- 統計學生資訊;
- 輸出統計資訊,
- 釋放記憶體,
參考代碼:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct student{
char name[25];
char major[25];
int english;
int algebra;
int C;
int total;
};
int SICE=0,NE=0,IOT=0,ave_SICE=0,ave_NE=0,ave_IOT=0;
int ReadStudentInfo(const char* filename,struct student** pStudents);
void Count(struct student pStudents[], int num);
int main()
{
int num,i;
struct student *STU;
num=ReadStudentInfo("students.txt",&STU);
printf("學生資訊:\n");
printf("------------------------------------------------------\n");
printf("序號 姓 名 專業名稱 英語成績 線性代數成績 C成績 總成績\n");
for(i=0;i<num;i++)
{
printf("%4d %6s %8s %8d %12d %5d %6d\n",i+1,(STU+i)->name,(STU+i)->major,(STU+i)->english,(STU+i)->algebra,(STU+i)->C,(STU+i)->total);
}
Count(STU,num);
printf("\n\n統計資訊:\n");
printf("------------------------------------------------------\n");
printf("序號 專業名稱 學生人數 平均成績\n");
printf("%4d %8s %8d %8d\n",1,"通信",SICE,ave_SICE);
printf("%4d %8s %8d %8d\n",2,"網路",NE,ave_NE);
printf("%4d %8s %8d %8d\n",3,"物聯網",IOT,ave_IOT);
free(STU);
//printf("%d %d %d %d %d %d",SICE,NE,IOT,ave_SICE,ave_NE,ave_IOT);
return 0;
}
int ReadStudentInfo(const char* filename,struct student** pStudents)
{
FILE* fp;
int num=0,i;
char str[50];
if((fp=fopen(filename,"r"))==NULL) return -1;
while(fgets(str,100,fp)!=NULL) num++;
fseek(fp,0,SEEK_SET);
*pStudents=(struct student*)malloc(sizeof(struct student)*num);
for(i=0;i<num;i++)
{
fscanf(fp,"%s %s %d %d %d",(*pStudents+i)->name,(*pStudents+i)->major,&(*pStudents+i)->english,&(*pStudents+i)->algebra,&(*pStudents+i)->C);
(*pStudents+i)->total=(*pStudents+i)->english+(*pStudents+i)->algebra+(*pStudents+i)->C;
//fread((*pStudents+i),sizeof(struct student),1,fp);
}
fclose(fp);
return num;
}
void Count(struct student pStudents[], int num)
{
int i;
for(i=0;i<num;i++)
{
if(strcmp(pStudents[i].major,"通信")==0)
{
SICE++;
ave_SICE+=pStudents[i].total;
}
if(strcmp(pStudents[i].major,"網路")==0)
{
NE++;
ave_NE+=pStudents[i].total;
}
if(strcmp(pStudents[i].major,"物聯網")==0)
{
IOT++;
ave_IOT+=pStudents[i].total;
}
}
ave_SICE/=SICE;
ave_NE/=NE;
ave_IOT/=IOT;
}
講解:
注意:運行此程式時,請確保源代碼與“students.txt”在同一目錄下,
實驗8主要考察:檔案輸入/輸出,結構體指標運用,動態記憶體,
有關檔案輸入/輸出這里引入相關鏈接:點擊進入,
己見:由于實驗報告說的并不清楚,所以只能寫出針對本題附件中“students.txt”的相關操作,如果另有測驗檔案,例如增加專業“計算機”等,本程式無法實作,另外對于題目中的設計帶引數的宏,我不解,直接用strcmp()不是很好嗎,當然,如果有小伙伴追求更快更強更完美,可以自行修改count函式,使用帶參宏,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/375023.html
標籤:其他
上一篇:STC15W408AS單片機IIC驅動0.96寸OLED顯示
下一篇:汽車電子設計之SBC芯片簡單認識
