接續前文文件打開操作,本文系統講解 C 語言四種核心文件讀寫方式:字符、字符串、塊、格式化讀寫,附帶完整示例代碼與執行結果分析。
函數原型
int fputc(int ch, FILE *fp); // 成功返回寫入字符,失敗返回 EOF(-1)
int fgetc(FILE *fp); // 成功返回讀取字符,失敗返回 EOF(-1)
關鍵特性
fputc 只寫入參數低 8 位;fgetc 只返回 1 字節數據fgetc 返回 EOF(-1) 有兩種情況——文件結束或讀取出錯int 類型變量接收,不可用 char,否則無法區分有效數據 0xFF 與 EOF測試代碼
#include
#include
int main() {
FILE *fp;
int ch;
if ((fp = fopen("test.txt", "wb+")) == NULL) {
printf("can not open file\n"); exit(0);
}
fputc(-1, fp); // 寫入 0xFF
fputc(385, fp); // 僅寫入低 8 位 0x81 (385 = 0x181)
rewind(fp);
ch = fgetc(fp);
while (feof(fp) == 0) {
printf("%d\n", ch);
ch = fgetc(fp);
}
fclose(fp);
return 0;
}
輸出結果
255 // 0xFF
129 // 0x81
若用 char ch 則輸出 -1、-127(符號擴展導致誤判)。
函數原型
int fputs(const char *s, FILE *fp); // 成功返回非負值,失敗返回 -1
char *fgets(char *s, int n, FILE *fp); // 讀取 n-1 字符或遇到 '\n' 結束,末尾自動加 '\0'
關鍵行為:fgets 遇到換行符 '\n' 會提前結束讀取(包含換行符)。
測試代碼
fputc('A', fp); fputc('B', fp); fputc('\n', fp); fputc('C', fp);
rewind(fp);
fgets(s, 5, fp); // 讀取 "AB\n",實際存入 "AB\0"
printf("%s\n", s); // 輸出 AB
函數原型
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
適用場景:結構體、數組等二進制數據批量讀寫。
核心規則:fread/fwrite 必須成對使用,否則數據解析錯誤。
測試代碼
typedef struct { char name[20]; double score; int age; } Student;
Student s1[3] = {{"liudehua",85.5,45},{"zhangxueyou",79.3,47},{"guofucheng",83.4,43}};
Student s2[3];
fwrite(s1, sizeof(Student), 3, fp); // 寫入 3 個結構體
rewind(fp);
fread(s2, sizeof(Student), 3, fp); // 讀出 3 個結構體
輸出:完整保留結構體所有字段數值。
函數原型
int fprintf(FILE *fp, const char *format, ...);
int fscanf(FILE *fp, const char *format, ...);
本質區別:以文本形式存儲數據(人類可讀),而非二進制內存映像。
fprintf/fscanf 必須成對使用'\n' 會轉換為 '\r\n'(Windows),二進制模式不轉換測試對比
// 格式化寫入
fprintf(fp, "%s %lf %d\n", s1[i].name, s1[i].score, s1[i].age);
// 文件內容:liudehua 85.500000 45\n (可讀文本)
// 塊寫入
fwrite(s1, sizeof(Student), 3, fp);
// 文件內容:二進制內存映像 (不可直接閱讀)
| 方式 | 存儲形式 | 適用數據 | 跨平台 | 可讀性 |
|---|---|---|---|---|
| 字符 | 逐字節 | 簡單文本 | 好 | 高 |
| 字符串 | 行文本 | 文本行 | 好 | 高 |
| 塊 | 二進制內存像 | 結構體/數組 | 需注意對齊/大小端 | 低 |
| 格式化 | 文本格式 | 各類基本類型 | 好 | 高 |
fprintf/fscanf 或 fgets/fputsfread/fwrite,注意結構體對齊與端序feof() 配合 int 類型接收返回值"wb"/"rb",文本用 "w"/"r",避免換行符轉換差異掌握四種讀寫模式的特性與適用場景,是 C 語言文件處理的核心功力。