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

C語言文件讀寫函數全解析:fscanf/fprintf、fgets/fputs、fread/fwrite 對比與實戰

     編輯:關於C語言

C語言文件讀寫函數全解析:fscanf/fprintf、fgets/fputs、fread/fwrite 對比與實戰

C標準庫提供三組成對的文件讀寫函數,分別面向格式化文本、行文本、二進制塊。本文系統對比其原型、行為差異、適用場景,並給出結構體數組讀寫實戰模式。

一、格式化文本:fscanf / fprintf

1. fscanf —— 從文本文件按格式讀取

int fscanf(FILE *fp, const char *format, ...);
// 示例:讀兩個整數
fscanf(fp, "%d%d", &a, &b);
  • 與 scanf 類似,但輸入源為文件指針 fp。
  • 文件中數據需以空白字符分隔(空格、制表符、換行符)。
  • fscanf(stdin, ...) 等價於 scanf(...)。
  • 返回值:成功返回賦值項數,失敗/EOF返回 EOF。

2. fprintf —— 按格式寫入文本文件

int fprintf(FILE *fp, const char *format, ...);
// 示例:寫兩個整數
fprintf(fp, "%d %d", x, y);
  • 與 printf 類似,輸出目標為文件。
  • 關鍵建議: 數據間必須加空格,便於後續 fscanf 正確解析;避免輸出額外標籤字符(如 "x=")。
  • fprintf(stdout, ...) 等價於 printf(...)。
  • 返回值:成功返回輸出字符數,失敗返回負值。

二、行文本:fgets / fputs

1. fgets —— 讀取一行(含換行符)

char *fgets(char *str, int n, FILE *fp);
  • 最多讀 n-1 字符,遇 \n 或 EOF 停止。
  • 保留換行符(若讀到),末尾自動加 \0。
  • 返回 str(成功)或 NULL(EOF/出錯)。
  • 適合逐行處理配置文件、日志。

2. fputs —— 寫入字符串(不自動換行)

int fputs(const char *str, FILE *fp);
  • 寫入 str 直到 \0(不寫入 \0),不自動加 \n。
  • 連續調用會導致字符串首尾相連,無分隔符。
  • 對策: 寫入前手動拼接 \n,或用 fprintf(fp, "%s\n", str)。
  • 返回非負(成功)或 EOF(失敗)。

三、二進制塊:fread / fwrite

原型

size_t fread(void *buffer, size_t size, size_t count, FILE *fp);
size_t fwrite(const void *buffer, size_t size, size_t count, FILE *fp);
  • buffer:內存緩衝區地址(讀入目標 / 寫出源)。
  • size:單個數據項字節數(如 sizeof(struct St))。
  • count:項數。
  • 實際傳輸字節數 = size * count,文件指針自動後移。
  • 返回值:實際完成的項數(count 或更少)。
  • 必須以二進制模式打開文件("rb"/"wb"/"rb+"),否則 Windows 下換行符轉換會損壞數據。

實戰:結構體數組寫入與讀取

struct St { char num[8]; float mk[5]; } pers[30];

// 寫入:逐個元素寫入(或一次性 fwrite(pers, sizeof(pers), 1, fp))
for(int i=0; i<30; i++)
    fwrite(&pers[i], sizeof(struct St), 1, fp);

// 讀取:利用 feof 判斷結束
int i = 0;
fread(&pers[i], sizeof(struct St), 1, fp);
while(!feof(fp)) {
    i++;
    fread(&pers[i], sizeof(struct St), 1, fp);
}

優勢: 保持內存佈局原貌,讀寫速度快,無格式轉換開銷,適合大數據量、結構體、圖像/音頻原始數據。

四、三組函數選擇指南

場景推薦函數關鍵注意
配置文件、CSV、人類可讀文本fscanf/fprintf空格分隔、格式字符串匹配
逐行處理文本、日志、未知長度行fgets/fputs保留\n、手動加\n、緩衝區大小
結構體數組、圖像數據、高性能持久化fread/fwrite二進制模式、結構體對齊、跨平台端序

五、常見坑點避雷

  1. fgets 讀到 \n 會保留,處理前需手動去除(str[strcspn(str,"\n")]=0)。
  2. fputs 不換行,連續寫入必須手動加 \n。
  3. fscanf 遇不匹配格式會停留在當前位置,導致死循環,需檢查返回值並清理輸入緩衝。
  4. 二進制文件不可跨平台直接拷貝(端序、對齊、類型大小差異),需序列化協議(如Protocol Buffers、自定義TLV)。
  5. 文件操作必須檢查返回值,fopen 失敗返回 NULL,讀寫函數返回項數 < 期望值 即為錯誤/EOF。

總結

掌握 fscanf/fprintf(格式化)、fgets/fputs(行文本)、fread/fwrite(二進制塊)三組函數的語義邊界與最佳實踐,是C語言文件處理的核心技能。根據數據性質(文本/二進制)、訪問模式(隨機/流式)、性能要求選擇合適組合,並始終遵循「檢查返回值、二進制模式、緩衝區邊界」三大鐵律。

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