C 語言將檔案視為字元串流,基本單位為位元組。所有操作函數宣告於 <stdio.h>。
FILE *fp = fopen("data.txt", "r"); // 唯讀
FILE *fp = fopen("data.bin", "wb"); // 二進位寫入
// 模式: r/w/a, + (讀寫), b (二進位)
// 開啟失敗回傳 NULL,必須檢查!
| 層級 | 函數 | 用途 |
|---|---|---|
| 字元 | fgetc() / fputc() | 逐字元處理,適合文字過濾 |
| 字串 | fgets() / fputs() | 逐行讀寫,保留換行符 |
| 格式化 | fscanf() / fprintf() | 按格式解析/生成,如 %d %s %f |
| 資料塊 | fread() / fwrite() | 二進位批量讀寫結構體/陣列,最高效 |
int fgetc(FILE *fp); // 回傳字元或 EOF
int fputc(int c, FILE *fp); // 成功回傳字元,失敗 EOF
char *fgets(char *s, int n, FILE *fp); // 讀 n-1 字元或遇 \n/EOF,末尾加 \0
int fputs(const char *s, FILE *fp); // 成功 0,失敗 EOF
int fprintf(FILE *fp, const char *fmt, ...);
int fscanf(FILE *fp, const char *fmt, ...);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *fp);
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *fp);
// 範例:寫入結構體陣列
struct student stu[20];
fwrite(&stu[1], sizeof(struct student), 2, fp); // 寫入第 1,2 元素
// 讀取單一結構體
struct student stu1;
fread(&stu1, sizeof(struct student), 1, fp);
int feof(FILE *fp); // 非零=已到 EOF
void rewind(FILE *fp); // 指標歸零
int fseek(FILE *fp, long offset, int whence); // whence: SEEK_SET/CUR/END
long ftell(FILE *fp); // 回傳當前位移,失敗 -1L
fseek(fp, 0, SEEK_END);
long size = ftell(fp);
fseek(fp, 0, SEEK_SET); // 歸零繼續讀寫
fopen 回傳值 → 解引用 NULL 崩潰。\n 轉換破壞資料,必須加 b 模式。fread/fwrite 忽略回傳值 → 無法偵測部分讀寫或錯誤。fflush(fp) 或關檔 fclose(fp) 強制寫入。fwrite → 只存指標值,重讀無效。需序列化或用固定長度陣列。#include <stdio.h>
#include <stdlib.h>
struct record { int id; char name[32]; double score; };
int main() {
struct record r = {101, "Alice", 92.5};
FILE *fp = fopen("records.dat", "wb");
if (!fp) { perror("open"); return 1; }
fwrite(&r, sizeof(r), 1, fp);
fclose(fp);
fp = fopen("records.dat", "rb");
struct record r2;
fread(&r2, sizeof(r2), 1, fp);
printf("%d %s %.1f\n", r2.id, r2.name, r2.score);
fclose(fp);
return 0;
}
掌握四層讀寫 API 並理解串流定位機制,是 C 語言處理持久化資料的核心能力。