首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言檔案操作基礎教程:fopen/fclose/fread/fwrite 完整範例

     編輯:關於C語言

檔案操作是 C 語言持久化資料的核心技能。本文系統講解標準 I/O 庫(stdio.h)的檔案指標模式:開啟模式對照表、錯誤處理、字元/字串/格式化/二進位讀寫、隨機存取(fseek/ftell)、緩衝區控制,並提供可編譯執行的完整範例程式。

1. 開啟檔案:fopen


FILE* fp = fopen("data.txt", "r"); // 失敗回傳 NULL
if (!fp) { perror("open failed"); exit(EXIT_FAILURE); }

開啟模式完整對照

模式說明檔案須存在寫入位置截斷
r唯讀是開頭否
w唯寫否(自動建立)開頭是
a附加否結尾否
r+讀寫是開頭否
w+讀寫否開頭是
a+讀寫附加否結尾否
rb/wb/ab/rb+/wb+/ab+二進位模式對應同上同上同上

Windows 下文字模式會將 \n ↔ \r\n 轉換,二進位模式不轉換,處理圖片/結構體必須加 b。

2. 關閉檔案:fclose / fcloseall


if (fclose(fp) != 0) { perror("close failed"); }
// fcloseall() 關閉所有開啟檔案,回傳關閉數量 (非標準,MSVC 支援)

⚠️ 未 fclose 導致緩衝區資料遺失、檔案損壞、檔案描述符洩漏(進程限制通常 512/1024)。

3. 字元讀寫


// 讀
int ch = fgetc(fp); // 回傳 unsigned char 轉 int,EOF(-1) 表示結束/錯誤
// 寫
fputc(ch, fp); // 成功回傳寫入字元,失敗回傳 EOF
// 等價巨集:getc/putc (可能為巨集,勿傳有副作用運算式)

複製檔案範例


while ((ch = fgetc(src)) != EOF) fputc(ch, dst);

4. 字串讀寫


// 讀一行 (含 \n,末尾加 \0),最多 n-1 字元
char buf[256];
fgets(buf, sizeof(buf), fp); // 遇 \n 或 EOF 停止,回傳 buf 或 NULL
// 寫字串 (不含 \0)
fputs(str, fp);

5. 格式化讀寫


fprintf(fp, "%d %s %.2f", id, name, score); // 寫
fscanf(fp, "%d %s %f", &id, name, &score);  // 讀,需傳址,回傳成功轉換項目數

6. 二進位塊讀寫:fread / fwrite


struct Student { int id; char name[20]; float gpa; };
Student stu = {1, "Alice", 3.8};
fwrite(&stu, sizeof(Student), 1, fp); // 寫入結構體
fread(&stu, sizeof(Student), 1, fp);  // 讀回

適用於結構體陣列、大量數值資料,速度遠快於格式化 I/O。

7. 隨機存取:fseek / ftell / rewind


fseek(fp, 0, SEEK_END);          // 移至檔尾
long size = ftell(fp);           // 取得檔案大小
fseek(fp, 0, SEEK_SET);          // 回到開頭
fseek(fp, -sizeof(Student), SEEK_END); // 讀取最後一筆記錄
起始點常數說明
檔案開頭SEEK_SEToffset ≥ 0
目前位置SEEK_CURoffset 可正負
檔案結尾SEEK_ENDoffset ≤ 0

8. 完整範例:學生成績管理


#include 
#include 
#include 

#define FILENAME "students.dat"
#define MAX 100

typedef struct { int id; char name[20]; float score; } Student;

void Add() {
    FILE* fp = fopen(FILENAME, "ab");
    Student s; printf("ID Name Score: "); scanf("%d %19s %f", &s.id, s.name, &s.score);
    fwrite(&s, sizeof(Student), 1, fp); fclose(fp);
}
void List() {
    FILE* fp = fopen(FILENAME, "rb");
    Student s; int i=1;
    while (fread(&s, sizeof(Student), 1, fp) == 1)
        printf("%2d: %4d %-10s %.1f\n", i++, s.id, s.name, s.score);
    fclose(fp);
}
int main() {
    int cmd;
    while (1) {
        printf("\n1.Add 2.List 0.Exit: "); scanf("%d", &cmd);
        if (cmd==1) Add(); else if (cmd==2) List(); else break;
    }
    return 0;
}

常見錯誤與對策

  • feof(fp) 迴圈條件錯誤:應檢查讀取函式回傳值,而非 !feof(fp)(會多讀一次)。
  • 緩衝區未刷新:關鍵資料寫入後呼叫 fflush(fp) 或 fclose(fp)。
  • 二進位檔跨平台不相容:結構體對齊、位元序差異,建議使用序列化庫(Protocol Buffers、MessagePack)或自訂封包格式。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved