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

C語言文件編程全攻略:文本/二進制流、標準I/O函數族、隨機訪問與錯誤處理

     編輯:關於C

文件流分類

類型特點適用場景
文本流字符序列,行結構(\n結尾),數據需格式化轉換配置文件、日誌、文本處理
二進制流字節序列,無轉換,double佔8字節原樣存儲數據庫、圖像、網絡包、高性能存儲

關鍵差異:Windows文本流\n↔\r\n轉換,二進制流無轉換。跨平台二進制文件必須用"rb"/"wb"。

核心API速查

打開/關閉

FILE *fopen(const char *path, const char *mode);
// mode: r/r+/w/w+/a/a+  加'b'為二進制
int fclose(FILE *fp); // 刷新緩衝區、釋放資源,成功返回0

字符/行級I/O

int fgetc(FILE *fp);           // 讀字符,EOF(-1)表示結束/錯誤
int fputc(int c, FILE *fp);     // 寫字符
char *fgets(char *s, int n, FILE *fp); // 讀行(含\n),n-1字符上限
int fputs(const char *s, FILE *fp);    // 寫行(不加\n)

格式化I/O

int fprintf(FILE *fp, const char *fmt, ...);
int fscanf(FILE *fp, const char *fmt, ...);
// 返回成功賦值項數,EOF表示讀取失敗

二進制塊I/O

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *fp);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *fp);
// 返回成功項數(nmemb),短於nmemb表示EOF/錯誤

隨機訪問

long ftell(FILE *fp);                    // 當前位置(字節偏移)
int fseek(FILE *fp, long offset, int whence); // whence: SEEK_SET/CUR/END
int fgetpos(FILE *fp, fpos_t *pos);       // 可移植位置獲取
int fsetpos(FILE *fp, const fpos_t *pos); // 配合fgetpos使用
void rewind(FILE *fp);                    // 等價 fseek(fp,0,SEEK_SET)

緩衝區控制

int fflush(FILE *fp);     // 強制寫入磁盤
void setbuf(FILE *fp, char *buf);   // 設置全緩衝/無緩衝
int setvbuf(FILE *fp, char *buf, int mode, size_t size);
// mode: _IOFBF/_IOLBF/_IONBF

錯誤處理最佳實踐

FILE *fp = fopen("data.bin", "rb");
if (!fp) {
    fprintf(stderr, "Open failed: %s\n", strerror(errno));
    return -1;
}

// 讀取檢查
if (fread(&val, sizeof(val), 1, fp) != 1) {
    if (feof(fp)) puts("EOF reached");
    else if (ferror(fp)) fprintf(stderr, "Read error: %s\n", strerror(errno));
}

// 寫入檢查
if (fwrite(&val, sizeof(val), 1, fp) != 1) {
    fprintf(stderr, "Write error: %s\n", strerror(errno));
}

fclose(fp); // 總是檢查返回值!磁盤滿時可能失敗

文件操作工具函數

int rename(const char *old, const char *new); // 原子重命名(同文件系統)
int remove(const char *path);                 // 刪除文件
// 必須在文件關閉後調用,否則行為未定義

常見坑點避雷

❌ 錯誤模式
  • while (!feof(fp)) { fread(...); } —— 多讀一次,應檢查fread返回值
  • fgets(buf, sizeof(buf), fp); buf[strlen(buf)-1] = '\0'; —— 空行時strlen=0下標越界
  • 文本模式下fseek非SEEK_SET 0 —— 行為未定義
  • fflush(stdin) —— 標準未定義,僅stdout/stderr保證有效
✅ 正確模式
  • while (fgets(buf, sizeof(buf), fp)) { ... }
  • 去除換行:buf[strcspn(buf, "\n")] = '\0';
  • 二進制文件隨機讀寫只用fseek/fread/fwrite
  • 關鍵數據fsync(fileno(fp)) (POSIX) 強制落盤
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved