1、int fseek(FILE *stream, long int offset, int where)這個函式的作用是將檔案位置指標從指定位置(where:系統有定義三個宏SEEK_SET:檔案頭、SEEK_CUR當前指標位置、SEEK_END檔案尾,當然你也可以自己指定位置,比如100、50這樣)移動個offset個位置(正數往後移,負數往前移);
2、void rewind(FILE *stream)這個很簡單,將位置指標指向檔案開頭;
3、long int ftell(FILE *stream)這個也很簡答,告訴你當前位置指標的位置(相對於檔案頭);
讀寫檔案在程式設計裡面應該是用的最多也最基礎的工作了。但是,C/C++中檔案讀寫方法有很多種,各種方法的使用場景區別甚大,到底日常工作中,我們什麼時候該用哪種方法呢?還是說隨便抓一種用就可以?
這篇文章就給大家分享一下C語言檔案的各種方法,下一篇再分享一下C++的讀寫方法:
在window環境下,檔案分別兩種,一種為文字檔案(用記事本可以開啟的檔案,如txt、xml、html、js等),一種為二進位制檔案(如圖片、軟體、壓縮包等)
讀寫文字檔案首先建立一個File物件,這個利用到系統庫中的fopen()函式,該函式返回一個File*型別的物件。
FILE *fopen( const char * filename, const char * mode );
第一個引數為:檔案路徑;第二個引數為開啟模式:這個是固定的,具體是什麼意思大家可以自己去查一下,沒什麼特別的,記住就好了。
1、文字檔案讀寫
接下來我們讀寫一個文字檔案,我新建一個test.txt檔案並且讀取出內容寫進newtest.txt檔案中,這裡有兩組函式fgetc/fputc和fgets/fputs函式,故名意意,fgetc是讀取出一個字元,而fgets是讀取一段字串,fputc是讀寫入一個字元,fputs寫進一段字串。我們分別來看一下:
int main(){ FILE * fpr = fopen("test.txt","r"); FILE * fpw = fopen("newtest.txt","w"); if(fpr && fpw) { while (!feof(fpr)) { char c = (char)fgetc(fpr); cout<<c; fputc(c,fpw); } } fclose(fpr); fclose(fpw); system("pause"); return 0 ;}注意:
1、feof是判斷是否讀取到檔案尾的函式,此處不用EOF來作為讀寫結束條件是因為:函式如fgetc或getc返回EOF並不一定表示檔案結束,當讀取檔案出錯時也會返回EOF,僅憑返回-1就認為檔案結束是錯誤的;正因為如此,我們需要feof()來判斷檔案是否結束,當然用feof()來判斷檔案結束時也需要判斷讀取操作是否出錯,這時可以用ferror()來判斷,當其為真時表示有錯誤發生。在實際的程式中,應該每執行一次檔案操作,就用用ferror函式檢測是否出錯。
2、fgetc()返回的是int,如果要在螢幕上打印出字元的話需要轉換為char;
上面是一個字元一個字元的讀,下面一段一段的讀:
FILE * fpr = fopen("test.txt","r"); FILE * fpw = fopen("newtest.txt","w"); if(fpr && fpw) { while (!feof(fpr)) { char* buff = new char[1024]; char* s = fgets(buff,3,fpr); cout<<s; fputs(s,fpw); } } fclose(fpr); fclose(fpw);這個方法個人不是很推薦,因為在使用過程中經常會報錯,這裡我如果將以此讀取的字串長度由3改為2或者1就會報錯,這個我也搞不清為什麼,如果有知道的朋友可以評論幫我解答一下;
讀寫二進位制檔案C語言讀寫二進位制檔案透過庫函式fread和fwrite實現:
size_t fread(void *buff, size_t sizeofElement, size_t count, FILE *stream);
size_t fwrite(const void *ptr, size_t sizeofElement, size_t count, FILE *stream);
引數解釋:buff:快取區地址
sizeofElement:每次讀/寫的資料大小
count:要多去多個個sizeofElement大小的資料
stream:檔案指標
現在我們來讀一張神仙姐姐的圖片test.ipg並且將讀取到的內容寫進newtest.jpg,然後檢視是否能開啟。
int main(){FILE * fpr = fopen("test.jpg","rb");FILE * fpw = fopen("newtest.jpg","wb");char* buff = new char[50];int len = 50;while (len==50){len = fread(buff,sizeof(char),50,fpr);fwrite(buff,sizeof(char),len,fpw);}fclose(fpr);fclose(fpw);system("pause");return 0 ;}執行結果,開啟newtest.jpg,結果完美呈現神仙姐姐。
注意以下幾點:
1、檔案開啟方式,不管是讀還是寫都需要在後面加b,b就是binary二進位制的意思,所以這裡開啟方式是“日本”和“wb”;
2、寫入fwrite中的count一定要注意,你的快取區存了多大的內容這裡就寫多大的內容,不然會導致檔案損壞,因為我定的是每次讀取50個char大小的內容,但是檔案大小不可能是50的整數啊,最後一次讀取的話他肯定會小於50,並且大小不能超過快取區的大小;
檔案內部位置指標
在開啟任何檔案的時候,都會有一個檔案內部位置指標。為什麼要在這裡介紹這個呢?我們大部分讀取檔案的時候都是不用去管他的,因為我們基本很少有讀取固定位置開始固定長度的需求,都是從開始一直讀取到檔案結束。
其實我們上面用到的那麼多函式,位置指標在檔案被開啟的時候位置指標是在零為,每讀取一次這個指標就會往後面移動你讀取的資料兩個距離。
這裡有三個函式:
1、int fseek(FILE *stream, long int offset, int where)這個函式的作用是將檔案位置指標從指定位置(where:系統有定義三個宏SEEK_SET:檔案頭、SEEK_CUR當前指標位置、SEEK_END檔案尾,當然你也可以自己指定位置,比如100、50這樣)移動個offset個位置(正數往後移,負數往前移);
2、void rewind(FILE *stream)這個很簡單,將位置指標指向檔案開頭;
3、long int ftell(FILE *stream)這個也很簡答,告訴你當前位置指標的位置(相對於檔案頭);
這可以幹嘛呢?最實用的,當然是快速的獲取檔案長度啊:
我們只需要用fseek將指標移動到檔案尾,再用ftell求出當前指標位置就是了:
fseek(fpr,OL,SEEK_END);注意這裡的offset一定要給0
ftell(fpr);