這是我的最后一次作業。
Part1.驗證性實驗
1.已知文本數據文件file1.dat,從文件file1.dat中讀入數據,找出最高分和最低分學生信息,並輸出在屏幕上已知文件file1.txt已經存在,將file1.txt中的小寫字母轉換成大寫后,轉存為file2.txt
// 將file1.txt中小寫字母轉換成大寫后,另存為file2.txt
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *fin, *fout; // 定義文件類型指針
int ch;
fin = fopen("file1.txt", "r"); // 以只讀文本方式打開文件file1.txt
if (fin == NULL) {
printf("fail to open file1.txt\n");
exit(0);
}
fout = fopen("d:\\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.已知文本數據文件file1.dat,從文件file1.dat中讀入數據,找出最高分和最低分學生信息,並輸出在屏幕上
// 從文本文件file1.dat中讀取數據,找出最高分和最低分學生信息,並輸出在屏幕上 #include <stdio.h> #include <stdlib.h> #define N 10 // 定義一個結構體類型STU typedef struct student { int num; char name[20]; int score; }STU; int main() { STU st, stmax, stmin; int i; FILE *fp; // 以只讀文本方式打開文件file1.dat fp = fopen("file1.dat", "r"); if( !fp ) { // 如果打開失敗,則輸出錯誤提示信息,然后退出程序 printf("fail to open file1.dat\n"); exit(0); } stmax.score = 0; // 先假定最高分是0,后面如發現比當前最高分還高的分數,就更新最高分 stmin.score = 100; // 先假定最低分是100分,后面如發現比當前最低分更低的分數,就更新最低分 for(i=0; i<N; i++) { fscanf(fp, "%d %s %d", &st.num, st.name, &st.score); // 從fp指定的文件中格式化讀取一個學生信息 if(st.score > stmax.score) stmax = st; else if(st.score < stmin.score) stmin = st; } fclose(fp); printf("最高分學生信息: %5d%15s%5d\n", stmax.num, stmax.name, stmax.score); printf("最低分學生信息: %5d%15s%5d\n", stmin.num, stmin.name, stmin.score); return 0; }
結果如下圖:
改寫第29行后,程序改寫為:
// 從文本文件file1.dat中讀取數據,找出最高分和最低分學生信息,並輸出在屏幕上 #include <stdio.h> #include <stdlib.h> #define N 10 // 定義一個結構體類型STU typedef struct student { int num; char name[20]; int score; }STU; int main() { STU st, stmax, stmin; int i; FILE *fp; // 以只讀文本方式打開文件file1.dat fp = fopen("file1.dat", "r"); if( !fp ) { // 如果打開失敗,則輸出錯誤提示信息,然后退出程序 printf("fail to open file1.dat\n"); exit(0); } stmax.score = 0; // 先假定最高分是0,后面如發現比當前最高分還高的分數,就更新最高分 stmin.score = 100; // 先假定最低分是100分,后面如發現比當前最低分更低的分數,就更新最低分 while(!feof(fp)) { fscanf(fp, "%d %s %d", &st.num, st.name, &st.score); // 從fp指定的文件中格式化讀取一個學生信息 if(st.score > stmax.score) stmax = st; else if(st.score < stmin.score) stmin = st; } fclose(fp); printf("最高分學生信息: %5d%15s%5d\n", stmax.num, stmax.name, stmax.score); printf("最低分學生信息: %5d%15s%5d\n", stmin.num, stmin.name, stmin.score); return 0; }
結果同上圖,這里就不在出圖了。
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中讀取數據到結構體數組st for(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.dat fout = fopen("file3.dat", "w"); if( !fout ) { // 如果打開失敗,則輸出錯誤提示信息,然后退出程序 printf("fail to open file1.dat\n"); exit(0); } // 將排序后的數組st中數據輸出到屏幕,同時,也寫入文件file3.dat for(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.dat return 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; } }
結果如下:
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中讀取數據到結構體數組st for(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.dat fout = 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.dat fwrite(st, sizeof(STU), N, fout); // 將從地址st開始的sizeof(STU)×N個字節信息寫入fout指向的文件file4.dat中 fclose(fout); // 關閉fout指向的文件file4.dat return 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; } }
結果如下:
發現亂碼了。這說明二進制文件數據在記事本程序里無法正常輸出,二進制文件與文本文件的區別:
1.能存儲的數據類型不同
文本文件只能存儲char型字符變量。二進制文件可以存儲char/int/short/long/float/……各種變量值。
2.每條數據的長度
文本文件每條數據通常是固定長度的。以ASCII為例,每條數據(每個字符)都是1個字節。進制文件每條數據不固定。如short占兩個字節,int占四個字節,float占8個字節……
3.讀取的軟件不同
文本文件編輯器就可以讀寫。比如記事本、NotePad++、Vim等。二進制文件需要特別的解碼器。比如bmp文件需要圖像查看器,rmvb需要播放器……
4.操作系統對換行符(‘\n’)的處理不同
文本文件,操作系統會對’\n’進行一些隱式變換,因此文本文件直接跨平台使用會出問題。
在Windows下,寫入’\n’時,操作系統會隱式的將’\n’轉換為”\r\n”,再寫入到文件中;讀的時候,會把“\r\n”隱式轉化為’\n’,再讀到變量中。
在Linux下,寫入’\n’時,操作系統不做隱式變換。
二進制文件,操作系統不會對’\n’進行隱式變換,很多二進制文件(如電影、圖片等)可以跨平台使用。
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 *fin; int i; // 以只讀文本方式打開文件examinee.txt fin = fopen("examinee.txt", "r"); if( !fin ) { // 如果打開失敗,則輸出錯誤提示信息,然后退出程序 printf("fail to open file\n"); exit(0); } for(i=0; i<n; i++) { if(fscanf(fin, "%ld %s %f %f", &s[i].id, s[i].name, &s[i].objective,&s[i].subjective)==0); // 從fin指定的文件中格式化讀取一個學生信息 printf("讀取錯誤!"); } fclose(fin);} // 輸出考生完整信息: 准考證號,姓名,客觀題得分,操作題得分,總分,等級 // 不僅輸出到屏幕上,還寫到文本文件result.txt中 void output(STU s[], int n) { int i; FILE *fout; // 以只讀文本方式打開文件result.txt fout=fopen("result.txt","w"); printf("准考證號 姓名 客觀題得分 操作題得分 總分 等級\n"); fprintf(fout,"准考證號 姓名 客觀題得分 操作題得分 總分 等級\n"); for(i=0; i<n; i++) { printf(" %-9ld%-10s%-13.2f%-10.2f%-7.2f%-8s\n", s[i].id,s[i].name,s[i].objective,s[i].subjective,s[i].sum,s[i].level); fprintf(fout," %-9ld%-10s%-13.2f%-10.2f%-7.2f%-8s\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,k; int a1,a2; a1=(int)(N*0.1),a2=(int)(N*0.5); STU temp; for(i=0;i<n;i++) s[i].sum=s[i].objective+s[i].subjective; for(j=0;j<n-1;j++) for(k=0;k<n-j-1;k++) if(s[k].sum<s[k+1].sum) { temp = s[k]; s[k] = s[k+1]; s[k+1] = temp; } for(i=0;i<a1;i++) strcpy(s[i].level,"優秀"); for(i=a1;i<a2;i++) strcpy(s[i].level,"合格"); for(i=a2;i<n;i++) strcpy(s[i].level,"不合格"); }
結果如下:
實驗總結:雖然這是最后一次實驗,但是我覺得這是7次實驗中最復雜的一次。在做實驗初,我一直找不到記事本,后來在同學的幫助下,才解決了這些問題。還是要抓緊時間練習,畢竟馬上就要考試了。
ps:這次因為技術問題,圖截的不是很好,請多擔待
互評網址:
https://www.cnblogs.com/astraeus/p/11062041.html
https://www.cnblogs.com/1418790233xjc/p/11068374.html
https://www.cnblogs.com/lizhangrui/p/11032563.html