C 語言檔案操作是系統程式設計的基石。新手常在「寫入正常但讀取失敗」或「二次開啟檔案失敗」上卡關。本文從檔案指標、開啟模式、緩衝區機制三個維度,徹底講透檔案讀寫核心邏輯。
每個 `FILE*` 指標內部維護一個位置指標(position indicator),記錄下一次讀寫的位置。關鍵操作對位置指標的影響:
FILE *fp = fopen("data.txt", "w");
fprintf(fp, "Hello"); // 寫入 5 字節,位置指標在第 5 字節後
// 此時直接 fgets/fread 會讀到 EOF,因為指標已在檔尾!
// 正確做法:重置指標
rewind(fp); // 或 fseek(fp, 0, SEEK_SET)
char buf[100];
fgets(buf, sizeof(buf), fp); // 正常讀到 "Hello"
常見原因:
#include
#include
int main() {
const char *filename = "data.txt";
FILE *fp = NULL;
char buffer[256];
// 1. 寫入
fp = fopen(filename, "w");
if (!fp) { perror("fopen write failed"); return 1; }
fprintf(fp, "Line 1\nLine 2\nLine 3\n");
fclose(fp); // 必須關閉,釋放鎖定、刷新緩衝區
// 2. 讀取(逐行)
fp = fopen(filename, "r");
if (!fp) { perror("fopen read failed"); return 1; }
while (fgets(buffer, sizeof(buffer), fp)) {
printf("讀到:%s", buffer); // fgets 保留換行符
}
fclose(fp);
// 3. 附加模式
fp = fopen(filename, "a");
if (!fp) { perror("fopen append failed"); return 1; }
fprintf(fp, "Appended line\n");
fclose(fp);
// 4. 二進位模式範例(結構體讀寫)
struct Student { int id; char name[20]; float score; } s = {1, "Tom", 92.5};
fp = fopen("student.dat", "wb");
if (fp) { fwrite(&s, sizeof(s), 1, fp); fclose(fp); }
fp = fopen("student.dat", "rb");
if (fp) { fread(&s, sizeof(s), 1, fp); fclose(fp); }
return 0;
}
掌握檔案指標位置、緩衝區特性與嚴謹的錯誤檢查,C 語言檔案操作就不再是「玄學」,而是可控、可預測的工程技能。