當(dāng)文件按指定的工作方式打開以后,就可以執(zhí)行對文件的讀和寫。下面按文件的性質(zhì)分類進(jìn)行操作。針對文本文件和二進(jìn)制文件的不同性質(zhì),對文本文件來說,可按字符讀寫或按字符串讀寫;對二進(jìn)制文件來說,可進(jìn)行成塊的讀寫或格式化的讀寫。 [例8-2] 將存放于磁盤的指定文本文件按讀寫字符方式逐個地從文件讀出,然后再將其顯示到屏幕上。采用帶參數(shù)的main( ),指定的磁盤文件名由命令行方式通過鍵盤給定。 [例8-3] 從鍵盤輸入字符,存到磁盤文件test.txt中: 2. 讀寫字符串 [例8-4] 向磁盤寫入字符串,并寫入文本文件test.txt: 運(yùn)行結(jié)束后,我們利用dos的type命令列表文件: [例8-5] 從一個文本文件test1.txt中讀出字符串,再寫入令一個文件test2.txt。 3. 格式化的讀寫 [例8-6] 將一些格式化的數(shù)據(jù)寫入文本文件,再從該文件中以格式化方法讀出顯示到屏
幕上,其格式化數(shù)據(jù)是兩個學(xué)生記錄,包括姓名、學(xué)號、兩科成績。 #i nclude<stdio.h> main( ) { FILE *fp; int i; struct stu{ /*定義結(jié)構(gòu)體類型*/ char name[15]; char num[6]; float score[2]; }student; /*說明結(jié)構(gòu)體變量*/ if((fp=fopen("test1.txt","w"))==NULL) { /*以文本只寫方式打開文件*/ printf("cannot open file"); exit(0); } printf("input data:\n"); for( i=0;i<2;i++) { scanf("%s %s %f %f",student.name,student.num,&student.score[0], &student.score[1]); /*從鍵盤輸入*/ fprintf(fp,"%s %s %7.2f %7.2f\n",student.name,student.num, st udent.score[0],student.score[1]); /* 寫入文件*/ } fclose(fp); /*關(guān)閉文件*/ if((fp=fopen("test.txt","r"))==NULL) { /*以文本只讀方式重新打開文件*/ printf("cannot open file"); exit(0); } printf("output from file:\n"); while (fscanf(fp,"%s %s %f %f\n",student.name,student.num,&student.score[0],student.score[1])!=EOF) / *從文件讀入* / printf("%s %s %7.2f %7.2f\n",student.name,student.num, student.score[0],student.score[1]); /* 顯示到屏幕*/ fclose(fp); /*關(guān)閉文件*/ } 程序設(shè)計(jì)一個文件變量指針,兩次以不同方式打開同一文件,寫入和讀出格式化數(shù)據(jù),有一點(diǎn)很重要,那就是用什么格式寫入文件,就一定用什么格式從文件讀,否則,讀出的數(shù)據(jù)與格式控制符不一致,就造成數(shù)據(jù)出錯。上述程序運(yùn)行如下: input data: xiaowan j001 87.5 98.4 xiaoli j002 99.5 89.6 output from file: xiaowan j001 87.50 98.40 xiaoli j002 99.50 89.60 列表文件的內(nèi)容顯示為:
c:\>type test.txt xiaowan j001 87.50 98.40 xiaoli j002 99.50 89.60 此程序所訪問的文件也可以定為二進(jìn)制文件,若打開文件的方式為: if ((fp=fopen("test1.txt","wb"))==NULL) { / * 以二進(jìn)制只寫方式打開文件* / printf("cannot open file"); exit(0); } 其效果完全相同。 4. 成塊讀寫
前面介紹的幾種讀寫文件的方法,對其復(fù)雜的數(shù)據(jù)類型無法以整體形式向文件寫入或從文件讀出。C語言提供成塊的讀寫方式來操作文件,使其數(shù)組或結(jié)構(gòu)體等類型可以進(jìn)行一次性讀寫。成塊讀寫文件函數(shù)的調(diào)用形式為: int fread(void *buf,int size,int count,FILE *stream) int fwrite(void *buf,int size,int count,FILE *stream) fread()函數(shù)從stream 指向的流文件讀取count (字段數(shù))個字段,每個字段為size(字段長度)個字符長,并把它們放到b u f(緩沖區(qū))指向的字符數(shù)組中。 fread()函數(shù)返回實(shí)際已讀取的字段數(shù)。若函數(shù)調(diào)用時要求讀取的字段數(shù)超過文件存放的字段數(shù),則出錯或已到文件尾,實(shí)際在操作時應(yīng)注意檢測。 fwrite( )函數(shù)從buf(緩沖區(qū))指向的字符數(shù)組中,把count(字段數(shù))個字段寫到stream所指向的流中,每個字段為size個字符長,函數(shù)操作成功時返回所寫字段數(shù)。 關(guān)于成塊的文件讀寫,在創(chuàng)建文件時只能以二進(jìn)制文件格式創(chuàng)建。 [例8-7] 向磁盤寫入格式化數(shù)據(jù),再從該文件讀出顯示到屏幕。
#i nclude "stdio.h" #i nclude "stdlib.h" main( ) { FILE *fp1; int i; struct stu{ / *定義結(jié)構(gòu)體*/ char name[15]; char num[6]; float score[2]; }student; if((fp1=fopen("test.txt","wb"))==NULL) { /*以二進(jìn)制只寫方式打開文件* / printf("cannot open file"); exit(0); } printf("input data:\n"); for( i=0;i<2;i++) { scanf("%s %s %f %f",student.name,student.num,&student.score[0],&student.score[1]); /* 輸入一記錄*/ fwrite(&student,sizeof(student),1,fp1); /* 成塊寫入文件*/ } fclose(fp1); if((fp1=fopen("test.txt","rb"))==NULL) { /*重新以二進(jìn)制只寫打開文件*/ printf("cannot open file"); exit(0); } printf("output from file:\n"); for (i=0;i<2;i++) { fread(&student,sizeof(student),1,fp1); /* 從文件成塊讀*/ printf("%s %s %7.2f %7.2f\n",student.name,student.num,student.score[0],student.score[1]); /* 顯示到屏幕*/ } fclose(fp1); } 運(yùn)行程序: input data: xiaowan j001 87.5 98.4 xiaoli j002 99.5 89.6 output from file: xiaowan j001 87.50 98.40 xiaoli j002 99.50 89.60 通常,對于輸入數(shù)據(jù)的格式較為復(fù)雜的話,我們可采取將各種格式的數(shù)據(jù)當(dāng)做字符串輸入,然后將字符串轉(zhuǎn)換為所需的格式。C提供函數(shù): int atoi(char *ptr) float atof(char *ptr) long int atol(char *ptr) 它們分別將字符串轉(zhuǎn)換為整型、實(shí)型和長整型。使用時請將其包含的頭文件math.h或stdlib.h寫在程序的前面。 |
|