1. fopen
— 打開文件
函數原型:
FILE *fopen(const char *filename, const char *mode);
參數:
-
filename
:要打開的文件名,可以是相對路徑或絕對路徑。 -
mode
:文件打開模式,表示文件的操作方式(如只讀、寫入、追加等)。
常見的打開模式:
-
"r"
:只讀模式,文件必須存在。 -
"w"
:只寫模式,如果文件存在會清空文件,不存在則創建。 -
"a"
:追加模式,文件不存在則創建,寫入時數據會追加到文件末尾。 -
"r+"
:讀寫模式,文件必須存在。 -
"w+"
:讀寫模式,文件存在則清空,不存在則創建。 -
"a+"
:讀寫模式,文件不存在則創建,數據追加到文件末尾。
返回值:
-
如果成功,返回一個指向文件的指針(
FILE *
)。 -
如果失敗,返回
NULL
,通常使用perror()
或errno
獲取錯誤信息。
示例:
FILE *fp = fopen("example.txt", "r");
if (fp == NULL) {perror("無法打開文件");return 1;
}
注意事項:
-
fopen
只支持文本文件和二進制文件的打開,打開方式非常靈活,可以通過不同的模式選擇合適的文件操作。 -
打開文件后,應確保及時關閉文件,使用
fclose()
。 -
fopen
函數會自動創建文件指針,并為文件分配緩沖區。
2. fread
— 從文件讀取數據
函數原型:
size_t fread(void *ptr, size_t size, size_t count, FILE *stream);
參數:
-
ptr
:指向要存儲讀取數據的內存緩沖區。 -
size
:每個元素的字節數(通常為sizeof(type)
)。 -
count
:要讀取的元素數量。 -
stream
:文件指針,表示要讀取的文件。
返回值:
-
返回實際讀取的元素數量。如果返回值小于
count
,表示可能發生了錯誤或到達了文件末尾(EOF
)。
示例:
FILE *fp = fopen("example.txt", "r");
if (fp == NULL) {perror("無法打開文件");return 1;
}char buffer[100];
size_t bytesRead = fread(buffer, sizeof(char), sizeof(buffer), fp);
if (bytesRead > 0) {printf("讀取到的內容: %s\n", buffer);
}
fclose(fp);
注意事項:
-
fread
是基于緩沖區的讀取,性能較高,適合讀取大塊數據。 -
讀取時要確保
ptr
的內存空間足夠容納讀取的數據。 -
fread
適用于二進制數據的讀取。如果是讀取文本數據,最好使用fgets
。 -
fread
讀取時并不會自動添加字符串終止符\0
,如果讀取的是字符串,需手動添加。
3. fwrite
— 向文件寫入數據
函數原型:
size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);
參數:
-
ptr
:指向要寫入的數據的內存緩沖區。 -
size
:每個元素的字節數(通常為sizeof(type)
)。 -
count
:要寫入的元素數量。 -
stream
:文件指針,表示要寫入的文件。
返回值:
-
返回實際寫入的元素數量。如果返回值小于
count
,表示可能發生了錯誤。
示例:
FILE *fp = fopen("output.txt", "w");
if (fp == NULL) {perror("無法打開文件");return 1;
}const char *data = "Hello, World!";
size_t bytesWritten = fwrite(data, sizeof(char), strlen(data), fp);
if (bytesWritten != strlen(data)) {perror("寫入文件失敗");
}
fclose(fp);
注意事項:
-
fwrite
會自動使用緩沖區,提高性能。 -
使用
fwrite
時應確保數據類型和緩沖區大小正確。通常用于寫入二進制數據。 -
fwrite
也不會在寫入的數據末尾自動添加字符串結束符\0
,需根據實際需求手動處理。
4. fseek
— 設置文件指針的位置
函數原型:
int fseek(FILE *stream, long int offset, int whence);
參數:
-
stream
:文件指針。 -
offset
:從whence
指定的起始位置開始的偏移量。 -
whence
:起始位置的標志,常用的值包括:-
SEEK_SET
:文件開頭。 -
SEEK_CUR
:當前位置。 -
SEEK_END
:文件末尾。
-
返回值:
-
成功時返回 0,失敗時返回非零值。
示例:
FILE *fp = fopen("example.txt", "r");
if (fp == NULL) {perror("無法打開文件");return 1;
}fseek(fp, 0, SEEK_END); // 定位到文件末尾
long fileSize = ftell(fp); // 獲取文件大小
printf("文件大小: %ld 字節\n", fileSize);fseek(fp, 0, SEEK_SET); // 重置文件指針到文件開頭
fclose(fp);
注意事項:
-
fseek
可以改變文件指針的位置,在讀取或寫入時可以靈活地控制文件位置。 -
fseek
和ftell
配合使用,能夠實現文件大小的獲取。 -
使用時要注意文件是否已正確打開,并且文件指針的偏移量是否合理。
5. fclose
— 關閉文件
函數原型:
int fclose(FILE *stream);
參數:
-
stream
:要關閉的文件指針。
返回值:
-
成功時返回 0,失敗時返回 EOF。
示例:
FILE *fp = fopen("example.txt", "r");
if (fp == NULL) {perror("無法打開文件");return 1;
}fclose(fp); // 關閉文件
注意事項:
-
必須關閉文件:每次打開文件后,使用完文件后必須調用
fclose()
關閉文件,釋放資源。 -
fclose()
會刷新文件的緩沖區,如果有未寫入的數據,會被強制寫入文件。 -
在程序結束時忘記關閉文件可能會導致內存泄漏或資源占用。
6. fputc
— 向文件寫入一個字符
函數原型:
int fputc(int character, FILE *stream);
參數:
-
character
:要寫入的字符。注意,這里傳入的是一個整數類型(通常是char
的 ASCII 值),而不是字符本身,因此需要使用字符類型轉換。 -
stream
:文件指針,指向目標文件。
返回值:
-
如果寫入成功,返回寫入的字符(轉換為
unsigned char
)。 -
如果寫入失敗,返回
EOF
。
示例:
#include <stdio.h>int main() {FILE *fp = fopen("example.txt", "w");if (fp == NULL) {perror("無法打開文件");return 1;}fputc('H', fp); // 向文件中寫入字符 'H'fputc('i', fp); // 向文件中寫入字符 'i'fclose(fp); // 關閉文件return 0;
}
注意事項:
-
fputc
只能寫入單個字符。寫入多個字符時,需要多次調用fputc
。 -
fputc
寫入時不會自動添加換行符,必須手動寫入(如fputc('\n', fp)
)。 -
如果寫入過程中發生錯誤,
fputc
返回EOF
,可以通過perror
或檢查文件指針的狀態進行處理。
7. fgetc
— 從文件讀取一個字符
函數原型:
int fgetc(FILE *stream);
參數:
-
stream
:文件指針,指向要讀取的文件。
返回值:
-
成功時,返回讀取的字符(以
unsigned char
形式返回,但作為int
類型)。 -
如果讀取到文件結束符(
EOF
),返回EOF
。 -
如果發生讀取錯誤,也會返回
EOF
。
示例:
#include <stdio.h>int main() {FILE *fp = fopen("example.txt", "r");if (fp == NULL) {perror("無法打開文件");return 1;}int ch;while ((ch = fgetc(fp)) != EOF) { // 逐個字符讀取文件內容putchar(ch); // 輸出字符}fclose(fp); // 關閉文件return 0;
}
注意事項:
-
fgetc
一次讀取一個字符,適用于逐字符讀取文件。 -
在讀取時,
fgetc
會返回字符的 ASCII 值。如果遇到文件結束符(EOF
),則停止讀取。 -
使用
fgetc
時要注意檢查返回值,EOF
可能意味著文件結束或讀取錯誤,因此應及時檢查并處理。
8. feof
— 檢查是否到達文件末尾
函數原型:
int feof(FILE *stream);
參數:
-
stream
:文件指針,指向要檢查的文件。
返回值:
-
如果文件指針已到達文件末尾,返回非零值(通常是
1
)。 -
如果文件指針尚未到達文件末尾,返回
0
。
示例:
#include <stdio.h>int main() {FILE *fp = fopen("example.txt", "r");if (fp == NULL) {perror("無法打開文件");return 1;}int ch;while ((ch = fgetc(fp)) != EOF) {putchar(ch); // 輸出字符}if (feof(fp)) {printf("\n已到達文件末尾。\n");}fclose(fp); // 關閉文件return 0;
}
注意事項:
-
feof
在文件讀取時用來檢查是否已到達文件末尾,它不會主動讀取文件內容,因此最好在文件讀取后使用(如通過fgetc
或fread
等函數)。 -
不要在
fgetc
、fread
等讀取函數調用前檢查feof
,因為feof
只能判斷是否到達文件末尾,而不是預測讀取是否成功。正確的做法是在讀取失敗或讀取結束后再檢查feof
。
總結
-
fopen
:用于打開文件,返回文件指針,可以設置文件的打開模式。 -
fread
:用于從文件中讀取數據,適用于讀取二進制數據。 -
fwrite
:用于將數據寫入文件,適用于寫入二進制數據。 -
fseek
:用于設置文件指針的位置,可以在文件內部進行定位。 -
fclose
:關閉文件,釋放資源,確保數據寫入完成。 -
fputc
:用于寫入單個字符,適合逐個字符地寫入文件。如果要寫入多個字符,可以多次調用fputc
,或者使用fwrite
。 -
fgetc
:用于讀取單個字符。返回值是一個int
類型,用于區分普通字符與EOF
(文件結束符)。 -
feof
:用于檢查文件是否已到達末尾,但不能在讀取文件時直接判斷文件是否結束。通常在文件讀取結束后,檢查feof
是否為真,來判斷是否到達文件末尾。
使用注意事項:
-
每次打開文件后,必須使用
fclose()
關閉文件,防止資源泄漏。 -
fread
和fwrite
操作時不會自動添加字符串結束符\0
,需要手動處理。 -
對于文本文件,使用
fopen
、fread
、fwrite
等標準庫函數進行文件操作,適用于大多數應用場景;對于高效、底層的文件操作,可以使用open
、read
、write
等系統調用。 -
調用
fseek
時要確保文件指針在有效范圍內。 -
fgetc讀取文件時,要根據返回值判斷是否讀取到文件結束。
-
feof
僅用于檢測文件末尾,而不是讀取是否成功。建議在fgetc
或fread
讀取后檢查feof
。