| 函數名 | 調用形式 | 功能 |
| fgetc | fgetc(fp) | 從fp指向的文件讀取一個字符 |
| fputc | fputc(ch,fp) | 把字符ch寫到文件指針變量fp所指向的文件中 |
| fgets | fgets(str,n,fp) | 從fp指向的文件中讀入一個長度為(n-1)的字符串,存放到字符數組str中,在str末尾添加一'\0' |
| fputs | fputs(str,fp) | 把字符數組str寫到fp所指向的文件中 |
1、向文件添加數據
#include <stdio.h>
#include <stdlib.h>
int main() { FILE *fp; char ch,filename[20]; printf("請輸入所用的文件名:"); scanf("%s",filename); if((fp=fopen(filename,"a"))==NULL) //打開輸出文件並使fp指向此文件 { printf("無法打開文件\n"); //如果文件出錯,就輸出此文件無法打開的信息 exit(0); //終止程序 } ch=getchar(); //用來接收最后輸入的回車符 printf("請輸入一個將要存儲到磁盤的字符串(以#結束):"); ch=getchar(); //接收從鍵盤輸入的第一個字符 while(ch!='#') //當輸入'#'時結束循環 { fputc(ch,fp); //向磁盤文件輸出一個字符 putchar(ch); //將輸出的字符顯示在屏幕上 ch=getchar(); //再接收下一個從鍵盤輸入的字符 } fclose(fp); //關閉文件 putchar(10); //向屏幕輸出一個換行符 return 0; }
其中:
fp=fopen(filename,"a") 是指向文件添加數據;
fp=fopen(filename,"w")是指向文件寫數據;
fp=fopen(filename,"r")是指讀取文件的數據。
-----------------------------------------------------------------分割線-------------------------------------------------------------
2、將in指向的文件中的數據復制到out指向的文件
#include <stdio.h> #include <stdlib.h> int main() { FILE *in,*out; //定義指向FILE類型文件的指針變量 char ch,infile[20],outfile[20]; //定義兩個字符數組,分別存放兩個數據文件名 printf("輸入輸入文件的名字"); scanf("%s",infile); //輸入一個輸入文件的名字 printf("輸入輸出文件的名字"); scanf("%s",outfile); //輸入一個輸出文件的名字 if((in=fopen(infile,"r"))==NULL) //打開輸入文件 { printf("無法打開文件"); exit(0); } if((out=fopen(outfile,"w"))==NULL) //打開輸出文件 { printf("無法打開文件"); exit(0); } while(!feof(in)) //如果遇到輸入文件的結束標志 { ch=fgetc(in); //從輸入文件讀入一個字符,暫時放在變量ch中 fputc(ch,out); //將ch寫到輸出文件中 putchar(ch); //將ch顯示在屏幕上 } putchar(10); //完全顯示后換行 fclose(in); //關閉文件 fclose(out); return 0; }
1)在訪問磁盤文件時,是逐個字符進行的,訪問完一個字節后,當前訪問位置就指向下一個字符;
2)為了知道對文件的訪問是否完成,只需看文件讀寫位置是否移動到文件的末尾。用feof函數可以檢查到文件讀寫位置標記是否移動到了末尾,既磁盤文件是否結束。如果是函數值為0;
3)運行結果是將將in指向的文件中的數據復制到out指向的文件。前提是in指向的文件必須存在,out指向的文件如果不存在就新建立一個文件。
-----------------------------------------------------------------分割線-------------------------------------------------------------
3、從鍵盤讀入3組字符串,然后將字符串送到指定的磁盤文件中
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { FILE *fp; char str[3][10],temp[10]; //建立存放字符串的數組 int i,k,j; printf("Enter the string:\n"); for(i=0;i<3;i++) //輸入字符串 { gets(str[i]); } if((fp=fopen("F:\\123.txt","w"))==NULL) //打開磁盤文件 { printf("無法打開文件!\n"); exit(0); } printf("\n\n"); for(i=0;i<3;i++) { fputs(str[i],fp); //將字符串str寫到fp指向的文件中 fputc(10,fp); //向磁盤輸入一個換行符 puts(str[i]); //在屏幕上顯示 } fclose(fp); //關閉文件 return 0; }
-----------------------------------------------------------------分割線-------------------------------------------------------------
4、從指定文件中讀取字符串並顯示出來
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { FILE *fp; char str[3][10]; //建立存放字符串的數組 int i=0; if((fp=fopen("F:\\123.txt","r"))==NULL) //打開文件 { printf("無法打開文件!"); exit(0); } while(fgets(str[i],10,fp)!=NULL) //從fp指向的文件中讀取9個字符到str[i]中 { printf("%s",str[i]); //輸出讀取的字符串 i++; } fclose(fp); //關閉文件 return 0; }
1)在上一個代碼程序中已經將字符串加了換行符,在用fgets函數讀取字符串時,指定一次性讀取10個字符,但按照fgets函數規定如果遇到"\n"就結束字符串讀取,"\n"作為最后一個字符串讀到字符數組中;
2)由於讀入到字符串數組的每個字符串后面都有一個"\n",所以在向屏幕輸出時就不必再加一個"\n",而只要寫printf("%s",str[i]); 即可。
-----------------------------------------------------------------分割線-------------------------------------------------------------
5、用格式化的方式讀取文件
fprintf(文件指針,格式字符串,輸出表列)
例如:fprintf(fp,"%d,%.2f",i,f); 作用是將int型變量 i 和float變量 f 按照%d和%.2f的格式輸出到fp指向的文件中。若i=3,f=2.5,
fscanf(文件指針,格式字符串,輸入表列)
例如:fscanf(fp,"%d,%.2f",&i,&f); 作用是讀取磁盤文件中的int型變量與float型變量分別送給i和f。
用格式化方式對磁盤文件進行讀寫使用方便,容易理解。但是讀寫是先要將ASCII碼轉換成二進制形式再保存 在內存變量中,輸出時再轉換成ASCII碼輸出,花費較多時間。
-----------------------------------------------------------------分割線-------------------------------------------------------------
6、用二進制方式向文件讀寫一組數據
fread(buffer,size,count,fp);
fwrite(buffer,size,count,fp);
buffer是一個地址,是用來存放從文件讀入的數據的存儲區的起始地址。對於fwrite來說是要把從此地址開始的數據向文件輸出;
size要讀寫的字節數;
count是要讀寫多少個數據項(一個數據項是size);
fp是指針指向的文件。
例如:
1)fwrite(&stu,4,10,fp);&stu是一個數組的首地址。這個函數將數組stu的10個4字節的數據存儲到文件指針fp指向的文件中。
實例:將結構體數組的數據寫到文件"F:\\123.txt"中
#include <stdio.h> #include <stdlib.h> #include <string.h> #define SIZE 3 struct Student //建立結構體數組 { char name[10]; int num; int age; char room_number[15]; }stu[SIZE]; void save() //編寫一個向文件寫數據的函數 { FILE *fp; //文件指針變量 int i; if((fp=fopen("F:\\123.txt","wb"))==NULL) //打開文件 { printf("無法打開文件!"); return; } for(i=0;i<SIZE;i++) { if(fwrite(&stu[i],sizeof(struct Student),1,fp)!=1) //向文件寫入數據 printf("文件讀寫錯誤!\n"); //錯誤提醒 } fclose(fp); //關閉文件 } int main() { int i; printf("請輸入學生數據:\n"); for(i=0;i<SIZE;i++) //給結構體數組輸入數據 scanf("%s%d%d%s",stu[i].name,&stu[i].num,&stu[i].age,stu[i].room_number); save(); return 0; }
2)fread(f,4,10,fp);其中f是一個float型數組名(代表數組首元素地址)。這個函數從fp指向的文件讀取10個4字節的數據存儲到數組f中。
實例:從文件"F:\\123.txt"中讀取數據存儲到結構體數組stu中
#include <stdio.h> #include <stdlib.h> #include <string.h> #define SIZE 3 struct Student //建立結構體數組 { char name[10]; int num; int age; char room_number[15]; }stu[SIZE]; int main() { FILE *fp; int i; if((fp=fopen("F:\\123.txt","rb"))==NULL) //打開文件 { printf("無法打開文件!"); exit(0); } for(i=0;i<SIZE;i++) { fread(&stu[i],sizeof(struct Student),1,fp); //從文件中讀取數據送到結構體數組中 printf("%-10s %4d %4d %-15s\n",stu[i].name,stu[i].num,stu[i].age,stu[i].room_number); //輸出讀取的數據 } fclose(fp); //關閉文件 return 0; }
注意:fwrite和fread函數一般用於二進制文件的讀寫。因為它們是按數據塊的長度來決定讀寫的,不出現字符轉換。
-----------------------------------------------------------------分割線-------------------------------------------------------------
7、隨機讀寫文件數據
(1)用rewind函數使文件位置標記指向文件開頭
rewind(FILE *)
rewind函數的作用是使文件位置標記重新指向文件開頭,此函數沒有返回值。
實例:將指定文件的內容顯示在屏幕上,然后復制到另一個文件中去
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { FILE *fp1,*fp2; fp1=fopen("F:\\123.txt","r"); //打開文件 fp2=fopen("F:\\321.txt","w"); //打開文件 while(!feof(fp1)) putchar(getc(fp1)); //從文件中讀取數據 putchar(10); //輸出一個換行 rewind(fp1); //使fp1重新指向文件的開頭 while(!feof(fp1)) putc(getc(fp1),fp2); //將fp1指向的文件中的數據寫入fp2中 fclose(fp1); //關閉文件 fclose(fp2); return 0; }
(2)用fseek函數改變文件位置標記
fseek(文件類型指針,位移量,起始點)
“起始點”用0、1、2代替,0表示“文件開始位置”,1表示“當前位置“,2表示”文件末尾位置“。
”位移量“指以”起始點“為起點,向前(后)移動的的字節數。位移量應該是long型數據(在數字的末尾加一個字母L,就表示是long型)。
fseek函數一般用於二進制文件
實例:將數據存入文件中,然后用fseek函數對文件位置標記重新標記,並將移位后的數據輸出到屏幕上
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { FILE *fp; int i; fp=fopen("F:\\123.txt","wb+"); //打開文件 char a[20]="123456789abcdefg"; for(i=0;i<20;i++) // 將數據寫入文件中 { fwrite(&a[i],sizeof(a[i]),1,fp); } fseek(fp,3L,0); //重新對文件位置標記進行定位 while(!feof(fp)) { putchar(fgetc(fp)); //將移位后的位置標記后面的數據輸出 } fclose(fp); //關閉文件 return 0; }
(3)用ftell函數測定文件位置標記的當前位置
ftell(FILE *)
ftell的作用是得到流式文件中位置標記的當前位置,用相對於文件開頭的位移量來表示。如果調用函數出錯,ftell函數的返回值為-1L。
實例:將一組數據寫入文件中,然后用fseek函數改變文件位置標記並在屏幕上顯示當前標記位置
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { FILE *fp; int i; fp=fopen("F:\\123.txt","wb+"); //打開文件 char a[20]="123456789abcdefg"; for(i=0;i<20;i++) // 將數據寫入文件中 { fwrite(&a[i],sizeof(a[i]),1,fp); } fseek(fp,3L,0); //重新對文件位置標記進行定位 i=ftell(fp); //獲取文件位置標記的當前位置 if(i==-1L) //出錯檢測 printf("錯誤!"); else printf("當前文件位置標記位置:%d\n",i); //輸出當前位置值 fclose(fp); //關閉文件 return 0; }
-----------------------------------------------------------------分割線-------------------------------------------------------------
8、文件讀寫的出錯檢測
(1)ferror函數
在調用各種文件輸入輸出函數(fputc、fgetc、fread、fwrite等)時,如果出現錯誤,可以用ferror函數檢查;
ferror(FILE *)
如果ferror函數的返回值是0(假),就表示並未出錯,如果返回一個非0值,就表示出錯了;
在執行fopen函數時,ferror函數的初始值自動重置為0;
在多次對一個文件調用輸入輸出函數時,每次調用都會使ferror函數值發生改變,所以,應該在每次調用輸入輸出函數時都進行一次ferror函數檢錯,以免信息丟失。
(2)clearerr函數
clearerr函數的作用是使文件錯誤標志和文件結束標記置為0,從而使文件恢復正常;
clearerr(FILE *)
比如在調用一次輸入輸出函數時出錯,ferror函數的值為一個非0值,應該立即使用clearerr函數使ferror函數值置為0,以便下次檢錯。
