1. 程式人生 > 實用技巧 >實驗七 檔案

實驗七 檔案

實驗七 檔案

任務三:

答:執行程式後,螢幕上確實輸出了按分數從高到低順序的資訊,同時,在當前路徑下,也生成了文字檔案file3.dat。用記事本程式開啟檔案file3.dat,裡面的資料資訊是正確的,並且是直觀可讀的。

任務四:

答:執行程式後,螢幕上確實正確輸出了按分數由高到底排序的學生資訊。同時,在當前路 徑下,也生成了二進位制檔案file4.dat,但是用記事本程式開啟檔案file4.dat時,裡面的資料資訊並不直觀可讀。相反,記事本檔案出現了亂碼的現象。因為程式四生成的是一個二進位制文字,而記事本無法識別。

#include <stdio.h>
#include <stdlib.h>
#define N 10
typedef struct student{
	int num;
	char name[20];
	int score;
}STU;
int main()
{
	FILE *fp;
	int i;
	STU st[N];
	fp=fopen("file4.dat","rb");
	if(!fp)
	{
		printf("fail to open file4.txt");
		exit(0);
	}
	fread(st,sizeof(STU),N,fp);
	for(i=0;i<N;i++)
	{
		printf("%-6d%-10s%3d\n", st[i].num, st[i].name, st[i].score);
	}
	fclose(fp);
	return 0;
	
}

  

任務五:

#include <stdio.h>
#include <string.h>
#include <stdlib.h> const int N = 10; // 定義結構體型別struct student,並定義其別名為STU typedef struct student { long int id; char name[20]; float objective; /*客觀題得分*/ float subjective; /*操作題得分*/ float sum; char level[10]; }STU; // 函式宣告 void input(STU s[], int n); void output(STU s[], int n); void process(STU s[], int n); int main() { STU stu[N]; printf("錄入%d個考生資訊: 准考證號,姓名,客觀題得分(<=40),操作題得分(<=60)\n", N); input(stu, N); printf("\n對考生資訊進行處理: 計算總分,確定等級\n"); process(stu, N); printf("\n列印考生完整資訊: 准考證號,姓名,客觀題得分,操作題得分,總分,等級\n"); output(stu, N); return 0; } // 從文字檔案examinee.txt讀入考生資訊:准考證號,姓名,客觀題得分,操作題得分 void input(STU s[], int n) { FILE *fp; int i; fp=fopen("examinee.txt","r"); if(fp==NULL) { printf("fail to open examinee.txt");
      exit(0); } for(i=0;i<n;i++) { fscanf(fp,"%ld %s %f %f",&s[i].id,s[i].name,&s[i].objective,&s[i].subjective); } fclose(fp); } // 輸出考生完整資訊: 准考證號,姓名,客觀題得分,操作題得分,總分,等級 // 不僅輸出到螢幕上,還寫到文字檔案result.txt中 void output(STU s[], int n) { FILE *fout; int i; fout=fopen("result.txt","w"); if(!fout) { printf("fail to open result.txt");
      exit(0); } printf("准考證號\t性名\t客觀題得分\t操作題得分\t總分\t等級\n"); for(i=0;i<n;i++) {
         fprintf(fout,"%-8ld\t%-4s\t%-10.2f\t%-10.2f\t-4.2f\t%-4s\n",s[i].id,s[i].name,s[i].objective,s[i].subjective,s[i].sum,s[i].level); printf("%-8ld\t%-4s\t%-10.2f\t%-10.2f\t%-4.2f\t%-4s\n",s[i].id,s[i].name,s[i].objective,s[i].subjective,s[i].sum,s[i].level); } fwrite(s,sizeof(STU),N,fout); fclose(fout); } // 對考生資訊進行處理:計算總分,排序,確定等級 void process(STU s[], int n) { STU t; int i,j,k,p=0; k=0; for(i=0;i<n;i++) { s[i].sum=s[i].objective+s[i].subjective; } for(i=0;i<n;i++) { k=i; for(j=i+1;j<n;j++) { if(s[j].sum>s[k].sum) { k=j; } } t=s[i]; s[i]=s[k]; s[k]=t; } for(i=0;i<n;i++) { switch(10*(i)/n) { case 0:strcpy(s[i].level,"優秀");break; case 1: case 2: case 3: case 4:strcpy(s[i].level,"合格");break; case 5: case 6: case 7: case 8: case 9:strcpy(s[i].level,"不合格");break; default:break; } } }

  

任務六:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 80
typedef struct student{
	int num;
	long id;
	char name[20];
	char inf[40];
}STU;
void input (STU st[]);
void onput(STU st[],int n);
int main()
{
	STU st[N];
	int n;
	input(st);
	while(scanf("%d",&n)!=EOF)
	{
		onput(st,n);
	}
	
	return 0;
}
	
void input (STU st[])
{
	FILE *fp;
	int i;
	fp=fopen("list.txt","r");
	if(!fp)
	{
		printf("fail to open list.txt");
		exit(0);
	}

	for(i=0;i<N;i++)
	{
		fscanf(fp,"%d %ld %s %s",&st[i].num,&st[i].id,st[i].name,st[i].inf );
	}
	fclose(fp);
	
}
void onput(STU st[],int n)
{
	FILE *fout;
	int i,a;
	fout=fopen("lucky.txt","w");
	if(!fout)
	{
		printf("fail to open lucky.txt");
		exit(0);
	}
	srand(time(NULL));
	for(i=0;i<n;i++)
	{
		a=rand()%N;
		printf("%d\t%ld\t%s\t%s\n",st[a].num ,st[a].id,st[a].name,st[a].inf);
		fprintf(fout,"%d\t%ld\t%s\t%s\n",st[a].num ,st[a].id,st[a].name,st[a].inf);
	}

	fclose(fout);

	
}

  

任務六的程式碼目前實現了根據需要的人數隨機抽點指定個人數的資訊,尚未解決了重複抽點到同一個人的狀況以及實現讀取當前系統日期作為檔名的功能。

實驗總結:本次實驗讓我切實地學會了如何編譯程式來呼叫其他文件的內容。也讓我對於二進位制檔案和文字檔案有了一個初步的瞭解。本章節由於涉及檔案的操作,又多了好多種函式,其中有關輸入輸出的函式大部分都與之前所學的函式存在相似性,尤其是“fscanf”和“fprintf”這一類格式化輸入輸出函式。

踩的坑:關於文字資料的輸入輸出,目前只擅長用“fscanf”和“fprintf”這類格式化輸入輸出函式,而在用到資料塊方式輸入輸出資料的時候,即用“fread”和“fwrite”這兩個函式時,老是出現亂碼的現象,給我帶來一定的麻煩。

尚存的問題:關於任務六的解決重複抽點到同一個人的狀況這一要求,不知道是將已經輸出的序號儲存到另外一個一維陣列中好,還是將原有的結構體陣列刪除已經輸出的資料好。另外,如果點到名的人數不限,考慮到所有人都被點到的可能性,編譯程式時可能也要考慮當所有人都被點到後,或剩餘未點到人數小於需要的人數時,程式自動報錯的情況。最後,關於格式化輸入輸出函式的使用,依舊未真正解決。