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

C語言文件操作核心 API 速查手冊:從 fopen 到 fseek

     編輯:關於C語言

文件操作核心流程

C 語言文件操作遵循「打開 → 讀寫 → 關閉」生命週期,核心圍繞 FILE* 指針展開。本文系統整理高頻 API,附帶模式表、返回值檢查與典型用法。

1. 文件打開與模式詳解

FILE *fopen(const char *path, const char *mode);

返回:成功返回文件指針,失敗返回 NULL 並設置 errno。

模式組合:

基礎含義二進制讀寫行為
r只讀rbr+/rb+文件必須存在
w只寫wbw+/wb+截斷或創建
a追加aba+/ab+定位末尾,創建或保留內容
關鍵差異:w 截斷文件,a 保留內容;+ 賦予讀寫雙向能力;b 禁用換行轉換。

2. 字符/行級讀寫

字符 I/O

int fgetc(FILE *fp);          // 讀取字符,EOF 表示結束/出錯
int fputc(int c, FILE *fp);   // 寫入字符,返回寫入字符或 EOF

// 典型讀取循環
int ch;
while ((ch = fgetc(fp)) != EOF) {
    process(ch);
}

getchar()/putchar() 分別等同於 getc(stdin)/putc(c, stdout)。

行 I/O

char *fgets(char *buf, int n, FILE *fp);  // 讀取至 \n 或 n-1 字符,保留 \n
int fputs(const char *s, FILE *fp);       // 寫入字符串(不含 \0)

// 典型逐行處理
char line[1024];
while (fgets(line, sizeof(line), fp)) {
    // line 以 \0 結尾,可能包含 \n
}
fgets 遇到 \n 會保留它,fputs 不寫入 \0。

3. 格式化讀寫

int fprintf(FILE *fp, const char *fmt, ...);  // 類似 printf
int fscanf(FILE *fp, const char *fmt, ...);   // 類似 scanf

// 典型用法
while (fscanf(fp, "%s %d", name, &score) == 2) {
    fprintf(stdout, "%s\t%d\n", name, score);
}

fscanf 成功返回匹配項數,失敗返回 EOF。

4. 二進制塊讀寫

size_t fread(void *buf, size_t size, size_t count, FILE *fp);
size_t fwrite(const void *buf, size_t size, size_t count, FILE *fp);
  • 返回實際讀寫的項數(非字節數)
  • 需以二進制模式(b)打開文件
  • 適用於結構體、數組的整體存取

5. 隨機訪問與位置控制

int fseek(FILE *fp, long offset, int whence);  // 返回 0 成功,非 0 失敗
long ftell(FILE *fp);                          // 返回當前偏移量,-1 表示錯誤

// whence 取值
#define SEEK_SET 0  // 文件開頭
#define SEEK_CUR 1  // 當前位置
#define SEEK_END 2  // 文件結尾

// 可移植的位置記錄/恢復
fpos_t pos;
fgetpos(fp, &pos);  // 記錄
fsetpos(fp, &pos);  // 恢復
fseek 配合 SEEK_END 可獲取文件大小:fseek(fp, 0, SEEK_END); long size = ftell(fp);

6. 文件維護操作

int fclose(FILE *fp);                    // 關閉,刷新緩衝區
int remove(const char *pathname);        // 刪除文件
int rename(const char *old, const char *new); // 重命名(文件需關閉)

7. 完整示例:學生成績二進制存儲

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX 100

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

Student stu[MAX];
int count = 0;

void save(const char *filename) {
    FILE *fp = fopen(filename, "wb");
    if (!fp) { perror("打開失敗"); return; }
    fwrite(&count, sizeof(int), 1, fp);
    fwrite(stu, sizeof(Student), count, fp);
    fclose(fp);
}

void load(const char *filename) {
    FILE *fp = fopen(filename, "rb");
    if (!fp) { perror("打開失敗"); return; }
    fread(&count, sizeof(int), 1, fp);
    fread(stu, sizeof(Student), count, fp);
    fclose(fp);
}

8. 避坑指南

  • 🚫 while(!feof(fp)) → ✅ 用讀取函數返回值控制循環
  • 🚫 文本模式用 fwrite 結構體 → ✅ 必須用二進制模式
  • 🚫 忽略 fopen 失敗 → ✅ 永遠檢查返回值
  • 🚫 讀寫切換不刷新/重定位 → ✅ 用 fflush/fseek
  • 🚫 大數組棧上分配 → ✅ 改用 malloc 或靜態/全局存儲
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved