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

C 語言文件操作函數大全:fopen/fread/fwrite/fseek/ftell 等核心 API 詳解與示例

     編輯:關於C語言

C 語言文件操作函數大全

核心分類

  • 打開/關閉:fopen, fclose, freopen, fdopen, fileno
  • 格式化讀寫:fprintf, fscanf, sprintf, sscanf, snprintf
  • 二進制塊讀寫:fread, fwrite
  • 字符/行讀寫:fgetc, fputc, fgets, fputs, getc, putc, getchar, putchar
  • 定位/狀態:fseek, ftell, rewind, fgetpos, fsetpos, feof, ferror, clearerr
  • 緩衝控制:setbuf, setvbuf, setbuffer, setlinebuf, fflush
  • 臨時文件:tmpfile, tmpnam, mktemp

高頻函數速查表

函數原型說明關鍵點
fopenFILE* fopen(const char* path, const char* mode)打開文件模式:r/w/a/r+/w+/a+ + b(二進制)。失敗返回 NULL
fcloseint fclose(FILE* stream)關閉文件刷新緩衝區,釋放資源。成功 0,失敗 EOF
fprintfint fprintf(FILE* stream, const char* fmt, ...)格式化寫入同 printf,輸出到文件
fscanfint fscanf(FILE* stream, const char* fmt, ...)格式化讀取同 scanf,遇空白/換行停止。返回匹配項數
fwritesize_t fwrite(const void* ptr, size_t size, size_t nmemb, FILE* stream)二進制塊寫入寫入 nmemb 個 size 字節項。返回實際寫入項數
freadsize_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream)二進制塊讀取返回實際讀取項數。需配合 feof/ferror 判斷原因
fseekint fseek(FILE* stream, long offset, int whence)移動文件指針whence: SEEK_SET/CUR/END。成功 0,失敗 -1
ftelllong ftell(FILE* stream)獲取當前位置返回距文件開頭字節數。失敗 -1
rewindvoid rewind(FILE* stream)指針歸零等價 fseek(stream,0,SEEK_SET),清除錯誤標志
feofint feof(FILE* stream)判斷文件結束非零=已到末尾。注意:讀操作失敗後才置位
ferrorint ferror(FILE* stream)判斷錯誤非零=發生錯誤。需 clearerr 重置
fflushint fflush(FILE* stream)刷新緩衝區強制寫入磁盤。stream=NULL 刷新所有流
setvbufint setvbuf(FILE* stream, char* buf, int mode, size_t size)設置緩衝模式_IOFBF 全緩衝/_IOLBF 行緩衝/_IONBF 無緩衝。須在讀寫前調用
fgetcint fgetc(FILE* stream)讀單字符返回 unsigned char 轉 int。EOF=-1 表示末尾/錯誤
fputcint fputc(int c, FILE* stream)寫單字符寫入低 8 位。返回寫入字符,失敗 EOF
fgetschar* fgets(char* s, int n, FILE* stream)讀一行讀 n-1 字符或遇換行。保留 \n。末尾補 \0
fputsint fputs(const char* s, FILE* stream)寫字符串不寫 \0。成功非負,失敗 EOF
getc/putc宏版 fgetc/fputc同功能,可能為宏參數求值副作用風險,優先用函數版
getchar/putchar宏 getc(stdin)/putc(c,stdout)標準輸入輸出同上
tmpfileFILE* tmpfile(void)創建臨時二進制文件自動刪除於關閉/程序結束。模式 wb+
removeint remove(const char* path)刪除文件成功 0。目錄需 rmdir 遞歸
renameint rename(const char* old, const char* new)重命名/移動跨文件系統可能失敗

經典使用模式

1. 文本配置文件讀寫

// 寫
FILE *fp = fopen("config.ini", "w");
fprintf(fp, "port=%d\n", 8080);
fprintf(fp, "host=%s\n", "127.0.0.1");
fclose(fp);

// 讀
fp = fopen("config.ini", "r");
int port; char host[64];
fscanf(fp, "port=%d\n", &port);
fscanf(fp, "host=%63s\n", host);
fclose(fp);

2. 二進制結構體序列化

struct Config { int port; char host[64]; double timeout; };
struct Config cfg = {8080, "127.0.0.1", 30.5};

// 寫
FILE *fp = fopen("config.bin", "wb");
fwrite(&cfg, sizeof(cfg), 1, fp);
fclose(fp);

// 讀
fp = fopen("config.bin", "rb");
struct Config rcfg;
fread(&rcfg, sizeof(rcfg), 1, fp);
fclose(fp);
// 注意:跨平台/編譯器需處理對齊、大端序、類型大小差異

3. 獲取文件大小

FILE *fp = fopen("data.bin", "rb");
fseek(fp, 0, SEEK_END);
long fsize = ftell(fp);
fseek(fp, 0, SEEK_SET); // 歸零繼續讀
fclose(fp);

4. 安全的逐行讀取

char line[1024];
while (fgets(line, sizeof(line), fp)) {
    // 處理 line,含換行符
    line[strcspn(line, "\n")] = 0; // 去除換行
}

常見陷阱與避坑

  • feof 誤用:while(!feof(fp)) fread(...) 會多讀一次。正確:**以讀取函數返回值為循環條件**。
  • 格式化讀取停止規則:fscanf(fp, "%s", buf) 遇空白停止,**無法讀含空格字符串**。改用 fgets 或 %[^\n] 掃描集。
  • 二進制結構體直接讀寫:僅限**同平台、同編譯器、同版本**程序互通。跨平台必須定義協議(文本/Protobuf/自定義)。
  • 緩衝區未刷新:異常退出導致數據丟失。關鍵節點調用 fflush 或設置無緩衝 setvbuf(fp, NULL, _IONBF, 0)。
  • 文件描述符與 FILE* 混用:fileno(fp) 獲取 fd,但隨後直接 read/write 會破壞 FILE* 內部緩衝狀態。**二選一,不要混用**。

總結

C 文件操作核心是 FILE* 流抽象。掌握「模式選擇、格式化 vs 二進制、定位查詢、緩衝控制、錯誤判斷」五大維度,並避開 feof、fscanf 空白截斷、二進制可移植性等經典坑,即可編寫健壯、高效的文件處理代碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved