C 標準庫 <stdio.h> 提供檔案操作 API,核心類型 FILE* 封裝檔案描述符、緩衝區、位置指標。本文系統整理開關、讀寫、定位、錯誤檢測與 12 種開檔模式。
FILE *fp = fopen("c:\\\\myfile", "r"); // 路徑雙反斜線轉義
if (!fp) { perror("fopen"); return -1; }
fclose(fp); // 成功返回 0,失敗返回 EOF(-1)
| 模式 | 說明 | 建立新檔 | 截斷既有 | 讀/寫位置 |
|---|---|---|---|---|
| r | 文字讀取 | 否 | 否 | 開頭 |
| w | 文字寫入 | 是 | 是 | 開頭 |
| a | 文字附加 | 是 | 否 | 結尾 |
| r+ | 文字讀寫 | 否 | 否 | 開頭 |
| w+ | 文字讀寫 | 是 | 是 | 開頭 |
| a+ | 文字讀寫附加 | 是 | 否 | 結尾(寫)/開頭(讀) |
| rb/wb/ab/rb+/wb+/ab+ | 二進位對應模式 | 同上 | 同上 | 同上 |
警告:"w" 會清空既有檔案內容,謹慎使用。
| 層級 | 函數 | 用途 |
|---|---|---|
| 字符 | fgetc/fputc | 單字符讀寫,返回 int (含 EOF) |
| 字串 | fgets/fputs | 行讀寫,fgets 保留換行,fputs 不自動換行 |
| 格式化 | fscanf/fprintf | 類 scanf/printf,轉換格式字串 |
| 二進位塊 | fread/fwrite | 結構體/陣列批量讀寫,fwrite(ptr, size, count, fp) |
rewind(fp); // 回到開頭 fseek(fp, offset, origin); // origin: SEEK_SET(0)/SEEK_CUR(1)/SEEK_END(2) long pos = ftell(fp); // 當前位置偏移量,錯誤返回 -1L
feof(fp); // 是否讀到檔案結尾 (非預測,而是上次讀取已達 EOF) ferror(fp); // 是否發生錯誤 clearerr(fp); // 清除 EOF 與錯誤旗標
struct Student { int id; char name[20]; float score; };
Student s = {101, "Alice", 92.5};
// 寫入
FILE* fp = fopen("students.dat", "wb");
fwrite(&s, sizeof(Student), 1, fp);
fclose(fp);
// 讀回
fp = fopen("students.dat", "rb");
Student s2;
fread(&s2, sizeof(Student), 1, fp);
printf("%d %s %.1f\n", s2.id, s2.name, s2.score);
fclose(fp);
fopen 返回值,失敗時用 perror 或 strerror(errno) 診斷。b) 避免 Windows 換行轉換 (\n↔\r\n) 破壞資料。fread/fwrite 而非逐字符/格式化,效能差異可達 100 倍。fflush 或 fsync (POSIX) 確保落盤。std::fstream,RAII 自動管理生命週期。