文件操作的第一步是 fopen,本文詳細解析打開模式組合、路徑處理、以及 Windows 下文本/二進制模式的關鍵差異(換行符轉換)。
FILE* fopen(const char *path, const char *mode);
"C:\\test.txt"r/w/a/+ /b/t 組合而成| 模式 | 含義 | 文件必須存在 | 指針初始位置 | 清空內容 |
|---|---|---|---|---|
| r | 只讀 | 是 | 文件頭 | 否 |
| r+ | 讀寫 | 是 | 文件頭 | 否 |
| w | 只寫 | 否(不存在則創建) | 文件頭 | 是 |
| w+ | 讀寫 | 否 | 文件頭 | 是 |
| a | 追加只寫 | 否 | 文件頭* | 否 |
| a+ | 追加讀寫 | 否 | 文件頭* | 否 |
* 關鍵發現:追加模式打開後指針初始指向文件頭,只有執行寫操作時才會移至末尾(驗證代碼見下)。
文本模式(默認 t):
'\n' (0x0A) → 自動轉為 '\r\n' (0x0D 0x0A)'\r\n' → 自動轉為 '\n'二進制模式(b):
Unix/Linux 無差異(只有 '\n')。
// 1. 驗證追加模式指針初始位置
FILE *fp = fopen("test.txt", "a"); // 假設文件已有 "ABC"
printf("%d\n", ftell(fp)); // 輸出 0(文件頭)
fputs("test", fp);
printf("%d\n", ftell(fp)); // 輸出 7(寫入後位置)
// 2. 驗證換行符轉換
char s[] = {'A','B','\n','C'};
FILE *fp1 = fopen("test1.txt", "wt"); // 文本
FILE *fp2 = fopen("test2.txt", "wb"); // 二進制
for (int i=0; i<4; i++) {
fputc(s[i], fp1);
fputc(s[i], fp2);
}
// 用十六進制編輯器查看:
// test1.txt: 41 42 0D 0A 43 (多出 0D)
// test2.txt: 41 42 0A 43 (原始)
// 3. 讀取時的差異
// 文本讀取 test1.txt: 41 42 0A 43 (自動過濾 0D)
// 二進制讀取 test1.txt: 41 42 0D 0A 43 (保留 0D)
「公司項目曾因未區分文本/二進制模式,導致 Windows 寫入配置文件後 Linux 讀取解析失敗,排查耗時數日。務必顯式指定 'b' 模式處理二進制數據,文本協議明確約定換行符格式。」
"wb"/"rb"/"wb+"'\n' 作為換行"a"/"a+",記住指針初始在頭部"rb+"/"wb+",配合 fseek/ftell掌握 fopen 模式組合與文本/二進制語義差異,是 C 語言文件處理穩健性的基石。