🌟🌟作者主頁:ephemerals__
🌟🌟所屬專欄:C語言
目錄
引言
一、文件的打開和關閉
1.流
2.標準流
3.文本文件和二進制文件
4.控制文件打開與關閉的函數
二、文件的順序讀寫
三、文件的隨機讀寫
1.fseek函數
2.ftell函數
3.rewind函數
四、文件讀取結束的判定
總結
引言
? ? ? ? 我們在寫程序的時候,往往會將數據存放在變量當中。如果程序退出,內存回收,這些數據就會丟失。那么我們是否有辦法對這些數據進行持久化的保存,再次打開程序時數據仍然存在?答案是肯定的。而能夠做到這件事的就是:文件操作。
一、文件的打開和關閉
1.流
? ? ? ? 程序的數據需要輸出到外部設備,也需要從外部設備輸入。對于不同設備,輸入輸出方式各有不同。為了方便我們在對各種輸入輸出設備進行操作,就有了“流”這一高度抽象的概念。在c語言中,對文件,畫面,鍵盤等的輸入輸出操作都是同過“流”進行的。在一般情況下,我們想要寫入數據或者讀取數據,都需要打開流。
2.標準流
? ? ? ? c語言程序在啟動的時候,默認有三個流已經為我們打開:
stdin--標準輸入流,絕大多數情況下從鍵盤輸入。
stdout--標準輸出流,絕大多數情況輸出至顯示器上。
stderr--標準錯誤流,絕大多數情況輸出至顯示器上。
正因為這三個流已經默認打開,所以我們使用scanf、printf等函數就可以直接進行輸入輸出操作。
這三個流也是具有類型的,它們的類型是:文件指針(FILE*)。我們在進行文件操作的時候,通過文件指針變量就可以間接找到與它關聯的文件。
3.文本文件和二進制文件
????????根據數據的組織形式,數據文件被稱為文本文件或者二進制文件。 數據在內存中以二進制的形式存儲,如果不加轉換的輸出到外存的文件中,就是二進制文件。
????????如果要求在外存上以ASCII碼的形式存儲,則需要在存儲前轉換。以ASCII字符的形式存儲的文件就是文本文件。
?????????個數據在文件中是怎么存儲的呢?
????????字符?律以ASCII形式存儲,數值型數據既可以以ASCII形式存儲,也可以使用二進制形式存儲。如有整數10000,如果以ASCII碼的形式輸出到磁盤,則磁盤中占用5個字節(每個字符?個字節),而二進制形式輸出,則在磁盤上只占4個字節。
4.控制文件打開與關閉的函數
? ? ? ? 在了解了這些前置知識之后,我們切入正題--打開文件和關閉文件。c語言提供了兩個函數,它們分別負責文件的打開和關閉,原型如下:
打開文件:FILE * fopen ( const char * filename, const char * mode );
關閉文件:int fclose ( FILE * stream );
fopen函數有兩個參數,第一個參數是以字符串形式表示的文件名,第二個參數是文件的打開方式,用字符串表示。這個函數在使用的時候我們需要創建一個文件指針變量來接收,當文件打開失敗時,它會返回空指針。關于打開方式,在這里一一列舉:
打開方式 | 含義 | 如果指定的文件不存在 |
“r”(只讀) | 為了輸?數據,打開?個已經存在的?本?件 | 返回空指針 |
“w”(只寫) | 為了輸出數據,打開?個?本?件 | 建??個新的?件 |
“a”(追加) | 向?本?件尾添加數據 | 建??個新的?件 |
“rb”(只讀) | 為了輸?數據,打開?個?進制?件 | 返回空指針 |
“wb”(只寫) | 為了輸出數據,打開?個?進制?件 | 建??個新的?件 |
“ab”(追加) | 向?個?進制?件尾添加數據 | 建??個新的?件 |
“r+”(讀寫) | 為了讀和寫,打開?個?本?件 | 返回空指針 |
“w+”(讀寫) | 為了讀和寫,建立一個新的文本文件 | 建??個新的?件 |
“a+”(讀寫) | 打開?個?件,在?件尾進?讀寫 | 建??個新的?件 |
“rb+”(讀寫) | 為了讀和寫打開?個?進制?件 | 返回空指針 |
“wb+”(讀寫) | 為了讀和寫,建立?個新的?進制?件 | 建??個新的?件 |
“ab+”(讀寫) | 打開?個?進制?件,在?件尾進?讀和寫 | 建??個新的?件 |
對于fclose函數,它的參數是文件指針,用于關閉這個文件指針指向的文件。
接下來,我們嘗試打開和關閉一個文件:
#include <stdio.h>int main()
{FILE* pf = fopen("test.txt", "w");if (pf == NULL)//文件打開失敗則退出程序{perror("fopen");return 0;}printf("文件打開成功\n");fclose(pf);pf = NULL;//避免出現野指針,及時制空return 0;
}

可以看到,由于打開方式是“w”,該路徑下確實出現了一個名為“test.txt”的文件。
二、文件的順序讀寫
? ? ? ? 接下來介紹幾個函數,用于在文件當中讀取或者寫入數據。
函數名 | 功能 | 適?于 |
fgetc | 字符輸?函數 | 所有輸?流 |
fputc | 字符輸出函數 | 所有輸出流 |
fgets | ?本?輸?函數 | 所有輸?流 |
fputs | ?本?輸出函數 | 所有輸出流 |
fscanf | 格式化輸?函數 | 所有輸?流 |
fprintf | 格式化輸出函數 | 所有輸出流 |
fread | ?進制輸? | ?件輸?流 |
fwrite | ?進制輸出 | ?件輸出流 |
接下來我們嘗試使用一下fscanf和fprintf函數:
這兩個函數的第一個參數是一個文件指針,用于對文件數據進行讀取和寫入操作。之后的參數與scanf、printf函數相同。
#include <stdio.h>int main()
{FILE* pf = fopen("test.txt", "w");//要寫入數據,以寫的形式打開文件if (pf == NULL){perror("fopen");return 0;}fprintf(pf, "123456");//向文件中寫入數據fclose(pf);pf = NULL;return 0;
}
可以看到,數據已經寫入到文件當中了。接下來我們使用fscanf函數將文件數據打印到屏幕上:
#include <stdio.h>int main()
{char str[20] = { 0 };FILE* pf = fopen("test.txt", "r");//要讀取數據,以讀的形式打開文件if (pf == NULL){perror("fopen");return 0;}fscanf(pf, "%s", str);//讀取數據到str當中printf(str);fclose(pf);pf = NULL;return 0;
}

三、文件的隨機讀寫
1.fseek函數
? ? ? ? fseek函數的作用是根據文件指針的位置和偏移量來定位文件指針。它的原型如下:
int fseek ( FILE * stream, long int offset, int origin );
它的第一個參數是文件指針,第二個參數是相對于設置位置的偏移量,第三個參數是設置的位置。
c語言定義了三個宏,可選擇其中一個作為第三個參數:
SEEK_SET:文件的起始位置
SEEK_CUR:文件指針當前的位置
SEEK_END:文件的末尾
定位了文件指針之后,我們就可以在文件的指定位置處進行讀取或者寫入操作了。
2.ftell函數
????????ftell函數用于返回文件指針相對于起始位置的偏移量。函數原型:
long int ftell ( FILE * stream );
3.rewind函數
? ? ? ? rewind函數用于將文件指針的位置回到文件的起始位置。它的函數原型:
void rewind ( FILE * stream );
四、文件讀取結束的判定
? ? ? ? 1.對于文本文件,我們首先可以使用fgetc函數循環讀取文件中的字符,直到讀到EOF為止,說明文件讀取結束。
????????2.對于二進制文件,我們使用fread函數判斷其返回值:是否小于實際要讀的個數。如果小于,則說明讀取結束。
? ? ? ? 對于以上兩種情況,文件讀取結束時,我們可以繼續判斷文件讀取結束的原因。介紹兩個函數:feof和ferror。
????????feof函數用于判斷文件讀取結束的原因是否是遇到文件尾。它的原型如下:
int feof ( FILE * stream );
如果文件由于讀取到文件末尾而讀取結束,則返回EOF;如果是其他情況,則會返回0。
????????ferror函數用于判斷文件讀取結束的原因是否是出現I/O錯誤。原型如下:
int ferror ( FILE * stream );
如果文件由于出現I/O錯誤而讀取結束,則返回非0值;其他情況則返回0。
接下來我們嘗試寫一段代碼對文件讀取結束進行判斷:
#include <stdio.h>int main()
{int c = 0;FILE* fp = fopen("test.txt", "r");if (fp == NULL){perror("fopen");return 0;}while ((c = fgetc(fp)) != EOF)//返回EOF則讀取結束{putchar(c);}//判斷讀取結束的原因if (ferror(fp))puts("I/O錯誤\n");else if (feof(fp))puts("文件讀取結束\n");fclose(fp);fp = NULL;return 0;
}
總結
? ? ? ? 今天我們學習了文件操作相關的知識,了解了文件的打開關閉,寫入數據或者從文件讀取數據的方法,以及調整文件指針的函數,還有對文件讀取結束的判定。如果你覺得博主講的還不錯,就請留下一個小小的贊在走哦,感謝大家的支持???