C 語言將文件視為位元組流。程序啟動自動打開三個標準流:stdin(鍵盤)、stdout(屏幕)、stderr(錯誤輸出)。文件操作通過 FILE* 指針進行,內部封裝了文件描述符、緩衝區指針、標誌位等信息。
FILE 結構(_iobuf)包含:緩衝區指針 _ptr、剩餘字符數 _cnt、緩衝區基址 _base、標誌 _flag、文件描述符 _file 等。fopen 會在進程級表創建多個獨立項,各自維護獨立的文件位置指針。| 模式 | 說明 |
|---|---|
r | 只讀,文件必須存在 |
w | 只寫,創建或截斷 |
a | 追加寫入,創建或定位到末尾 |
r+ | 讀寫,文件必須存在 |
w+ | 讀寫,創建或截斷 |
a+ | 讀寫追加 |
二進制模式在字母後加 b(如 rb、wb),Windows 下影響換行符轉換。
FILE *fp = fopen("data.txt", "w");
if (!fp) { perror("open"); return 1; }
fprintf(fp, "%d %s %.2f\n", 100, "Alice", 123.45);
fclose(fp);
FILE *fp = fopen("data.txt", "r");
int id; char name[32]; double bal;
while (fscanf(fp, "%d %s %lf", &id, name, &bal) == 3)
printf("%d %s %.2f\n", id, name, bal);
fclose(fp);
rewind(fp) 將位置指針移回文件開頭,等價於 fseek(fp, 0, SEEK_SET)。
固定長度記錄(通常用 struct),配合 fseek、fread、fwrite 實現 O(1) 定位。
struct Record {
int id;
char name[20];
double balance;
};
FILE *fp = fopen("records.dat", "wb");
struct Record blank = {0};
for (int i = 0; i < 100; i++)
fwrite(&blank, sizeof(blank), 1, fp);
fclose(fp);
FILE *fp = fopen("records.dat", "rb+");
struct Record r = {10, "Bob", 500.0};
fseek(fp, (r.id-1)*sizeof(r), SEEK_SET); // 定位
fwrite(&r, sizeof(r), 1, fp);
fclose(fp);
FILE *fp = fopen("records.dat", "rb");
struct Record r;
fseek(fp, 5*sizeof(r), SEEK_SET); // 讀第6條
fread(&r, sizeof(r), 1, fp);
printf("%d %s %.2f\n", r.id, r.name, r.balance);
fclose(fp);
| 函數 | 用途 |
|---|---|
fopen/fclose | 打開/關閉文件 |
fprintf/fscanf | 格式化文本讀寫 |
fread/fwrite | 二進制塊讀寫 |
fseek/ftell | 位置定位/獲取(長整型偏移) |
fgetpos/fsetpos | 位置定位/獲取(fpos_t 類型) |
rewind | 回到文件開頭 |
feof/ferror/clearerr | 狀態檢查 |
setbuf/setvbuf | 設置緩衝模式 |
remove/rename | 刪除/重命名 |
tmpfile/tmpnam | 臨時文件 |
fopen 返回值,失敗時用 perror 輸出錯誤。\r\n vs Unix \n),二進制模式無此問題。b),確保偏移計算準確。fclose 釋放資源,刷新緩衝區。