实验七报告
一、實驗結論
part1:驗證性實驗
1.驗證性實驗2
如果事先不知道學生人數,嘗試對line29做如下修改后,程序運行結果是否正確?回答問題,并給出運行結果截圖。?
運行結果正確 // 將file1.txt中小寫字母轉換成大寫后,另存為file2.txt #include <stdio.h> #include <stdlib.h>int main() {FILE *fin, *fout; // 定義文件類型指針int ch;fin = fopen("file1.txt", "r"); // 以只讀文本方式打開文件file1.txtif (fin == NULL) {printf("fail to open file1.txt\n");exit(0); } fout = fopen("file3.txt", "w"); // 以寫文本方式打開文件file2.txt, 如果文件不存在,就創建一個if (fout == NULL) {printf("fail to open or create file2.txt\n");exit(0);} while( !feof(fin) ) {ch = fgetc(fin); // 從fin指向的文件file1.txt中讀取單個字符,暫存在字符變量ch中 if(ch >= 'a' && ch <= 'z') // 如果是小寫字母,則轉換成大寫 ch -= 32;fputc(ch, fout); // 將字符變量ch中的字符寫入fout指向的文件file2.txt中 }fclose(fin); fclose(fout);return 0; }?
2.對比驗證性實驗3和驗證性實驗4的程序源碼及運行結果,總結比較二進制文件與文本文件的區別。? 實驗3: // 從文本數據文件file1.dat中讀入數據,按成績從高到低排序,將排序結果輸出到屏幕上,同時以文本方式存入文件file3.dat中。 #include <stdio.h> #include <stdlib.h>#define N 10// 定義一個結構體類型STU typedef struct student {int num;char name[20];int score; }STU;void sort(STU *pst, int n); // 函數聲明 int main() {FILE *fin, *fout;STU st[N];int i;// 以只讀文本方式打開文件file1.dat fin = fopen("file1.dat", "r");if( !fin ) { // 如果打開失敗,則輸出錯誤提示信息,然后退出程序 printf("fail to open file1.dat\n");exit(0);}// 從fin指向的數據文件file1.dat中讀取數據到結構體數組stfor(i=0; i<N; i++) fscanf(fin, "%d %s %d", &st[i].num, st[i].name, &st[i].score);fclose(fin); // 關閉fin指向的文件file1.dat// 調用函數sort()對數組st中數據,按分數又高到低排序 sort(st, N);// 以寫方式打開/創建文本文件file3.datfout = fopen("file3.dat", "w");if( !fout ) { // 如果打開失敗,則輸出錯誤提示信息,然后退出程序 printf("fail to open file1.dat\n");exit(0);}// 將排序后的數組st中數據輸出到屏幕,同時,也寫入文件file3.datfor(i=0; i<N; i++) {printf("%-6d%-10s%3d\n", st[i].num, st[i].name, st[i].score);fprintf(fout, "%-6d%-10s%3d\n", st[i].num, st[i].name, st[i].score);}fclose(fout); // 關閉fout指向的文件file3.datreturn 0; }// 函數功能描述:對pst指向的n個STU結構體數據進行排序,按成績數據項由高到底排序 // 排序算法:冒泡法 void sort(STU *pst, int n) {STU *pi, *pj, t;for(pi = pst; pi < pst+n-1; pi++)for(pj = pi+1; pj < pst+n-1; pj++) if(pi->score < pj->score) {t = *pi;*pi = *pj;*pj = t; }} // 說明:冒泡排序算法是確定的,但其具體實現方式和細節卻是靈活多樣的 // 本例中,冒泡排序算法的函數體中,都是通過指針變量操作的。 // 而在前面章節的實例中,冒泡排序的函數體,有些是通過數組實現的,有些是指針和數組的混合 // 請結合代碼體會和理解,做到理解算法本質,才能應對和理解靈活多樣的實現形式實驗4:
// 從文本數據文件file1.dat中讀入數據,按成績從高到低排序,并將排序結果輸出到屏幕上,同時,也以二進制方式存入文件file4.dat中。 #include <stdio.h> #include <stdlib.h>#define N 10// 定義一個結構體類型STU typedef struct student {int num;char name[20];int score; }STU;void sort(STU *pst, int n); // 函數聲明 int main() {FILE *fin, *fout;STU st[N];int i;// 以只讀文本方式打開文件file1.dat fin = fopen("file1.dat", "r");if( !fin ) { // 如果打開失敗,則輸出錯誤提示信息,然后退出程序 printf("fail to open file1.dat\n");exit(0);}// 從fin指向的數據文件file1.dat中讀取數據到結構體數組stfor(i=0; i<N; i++) fscanf(fin, "%d %s %d", &st[i].num, st[i].name, &st[i].score);fclose(fin); // 關閉fin指向的文件file1.dat// 調用函數sort()對數組st中數據,按分數由高到低排序 sort(st, N);// 以寫方式打開/創建二進制文件file4.datfout = fopen("file4.dat", "wb");if( !fout ) { // 如果打開失敗,則輸出錯誤提示信息,然后退出程序 printf("fail to open file1.dat\n");exit(0);}// 將排序后的數組st中數據輸出到屏幕for(i=0; i<N; i++) printf("%-6d%-10s%3d\n", st[i].num, st[i].name, st[i].score);// 將排序后的數組st中數據寫到二進制文件file4.datfwrite(st, sizeof(STU), N, fout); // 將從地址st開始的sizeof(STU)×N個字節信息寫入fout指向的文件file4.dat中 fclose(fout); // 關閉fout指向的文件file4.datreturn 0; }// 函數功能描述:對pst指向的n個STU結構體數據進行排序,按成績數據項由高到底排序 // 排序算法:冒泡法 void sort(STU *pst, int n) {STU *pi, *pj, t;for(pi = pst; pi < pst+n-1; pi++)for(pj = pi+1; pj < pst+n; pj++) if(pi->score < pj->score) {t = *pi;*pi = *pj;*pj = t; }} // 說明:冒泡排序算法是確定的,但其具體實現方式和細節卻是靈活多樣的 // 本例中,冒泡排序算法的函數體中,都是通過指針變量操作的。 // 而在前面章節的實例中,冒泡排序的函數體,有些是通過數組實現的,有些是指針和數組的混合 // 請結合代碼體會和理解,做到理解算法本質,才能應對和理解靈活多樣的實現形式實驗三運行結果:
同時,在當前路徑下,生成了文本文件fifile3.dat。用記事本程序打開文件fifile3.dat,觀察里面的數據信息是正確的,并且是直觀可讀。實驗四運行結果:
同時,在當前路徑下,生成了二進制文件file4.dat。用記事本程序嘗試打開文件fifile4.dat,觀察里面的數據信息不直觀可讀。區別:
文本文件:數據以ASCⅡ碼形式存儲,也稱ASCⅡ碼文件 每個字節存放一個字符的ASCII碼;
二進制文件:數據按其在內存中的存儲形式原樣存放。
//寫一個簡單的程序,嘗試從二進制文件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 *fin;int i;STU st[N];if((fin= fopen("file4.dat","r"))==NULL) { printf("fail to open file\n");exit(0);}for(i=0;i<N;i++){fread(&st[i],sizeof(STU),N,fin); //使用塊讀寫函數讀取二進制文本中內容 }fclose(fin); FILE *fp;fp=fopen("file4_1.txt","w");if(fp==NULL){printf("fail to open file4_1.txt\n");} for(i=0;i<N;i++){printf("%d %s %d\n",st[i].num,st[i].name,st[i].score);}fwrite(st, sizeof(STU), N, fp);fclose(fp);return 0; }實驗結果:
注:黃色區域數據塊讀取函數fread可用于讀取二進制數據塊,不能使用fscanf函數,讀出來的是亂碼。
Part2: 編程練習 #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){ // 如果打開失敗,則輸出錯誤提示信息,然后退出程序printf("fail to open examinee.txt\n");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\n");exit(0);}for(i=0; i<n; i++){fprintf(fout,"%ld %s %f %f %f %s \n",s[i].id,s[i].name,s[i].objective,s[i].subjective,s[i].sum,s[i].level);printf("%ld %s %f %f %f %s \n",s[i].id,s[i].name,s[i].objective,s[i].subjective,s[i].sum,s[i].level);}fclose(fout); }// 對考生信息進行處理:計算總分,排序,確定等級 void process(STU s[], int n) {// 補足代碼int i,j;STU t;for(i=0; i<n; i++)s[i].sum=s[i].subjective*0.4+s[i].objective*0.6;for(i=0; i<n-1; i++){for(j=0; j<n-i-1; j++){if(s[j].sum<s[j+1].sum){t=s[j];s[j]=s[j+1];s[j+1]=t;}}}for(i=0;i<n;i++) { if(i<=n*0.1-1)strcpy(s[i].level,"優秀"); else if(i>n*0.1-1&&i<=n*0.5-1)strcpy(s[i].level,"合格");else strcpy(s[i].level,"不合格");} }實驗結果:
?
二、實驗感悟
1.驗證性實驗3,4中黃色標記的冒泡法不太懂,為什么兩個寫法不一樣?
2.在“寫一個簡單的程序,嘗試從二進制文件file4.dat中讀出數據,并在屏幕上顯示,以此查看文件file4.dat的內容。”中用了fscanf
但是結果亂碼,在觀看白云下的兔子的代碼時,發現了她也出現了同樣的問題:
黃色區域數據塊讀取函數fread可用于讀取二進制數據塊,不能使用fscanf()函數,讀出來的是亂碼。(為什么?)
3.特別特別注意,第3行的#include <stdlib.h>,需要特別注意,如果你使用了如第45行的exit(0);函數,就要加上這個文件調用了。(來自:白云下的兔子)
4.在補足程序的時候,沒注意到的小細節太多了,導致出現了下面的結果:
還是要多多加油啊
轉載于:https://www.cnblogs.com/xiaerhe/p/11073724.html
總結
- 上一篇: rabbitmq简单运用
- 下一篇: XPath语法规则及实例