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

Windows C 語言文件操作完整指南:文本/二進制、格式化/隨機讀寫、錯誤處理

     編輯:關於C語言

Windows 平台 C 語言文件 I/O 系統性掌握

文件操作是系統編程基石。本文基於 MSVC 運行庫,涵蓋文本/二進制模式、格式化讀寫、隨機訪問、錯誤處理、資源管理等核心技能,附帶完整可編譯示例代碼。

一、文件分類與編碼模式

二、fopen 模式字符串完全解析

FILE *fp = fopen("path", "mode");
維度類型說明
用戶視角普通文件磁盤數據,如文本、圖片、可執行文件
設備文件外設抽象:標準輸入 (鍵盤)、標準輸出 (顯示器)、串口、並口
編碼方式文本文件 (ASCII/UTF-8)字符流,每字符 1 字節 (ASCII) 或多字節 (UTF-8),有換行符轉換
二進制文件字節流,無任何轉換,結構體直接寫入,sizeof(int) 通常 4 字節

關鍵:b 表示二進制模式 (Windows 關鍵,禁用 \n↔\r\n 轉換);+ 表示讀寫雙向。

三、核心 API 分類速查

模式含義指針初始位置文件不存在文件存在
r/rb只讀開頭失敗保留內容
w/wb只寫開頭創建截斷為 0
a/ab追加結尾創建保留內容
r+/rb+讀寫開頭失敗保留內容
w+/wb+讀寫開頭創建截斷為 0
a+/ab+讀寫追加結尾創建保留內容

四、完整示例程序 (cFile.c)

#include "cFile.h"
#include "cHelper.h"  // 假設提供 str_concat2 等輔助

void file_demo1_write_text(const char *root) {
    char *path = str_concat2(root, "\\c_file_demo1.txt");
    FILE *fp = fopen(path, "wt+");  // 文本讀寫,創建/截斷
    if (!fp) { /* errno 處理 */ free(path); return; }

    fputc('w', fp);
    fputs("ebabcd\nwanglei", fp);
    fclose(fp);
    free(path);
}

void file_demo2_read_text(const char *root) {
    char *path = str_concat2(root, "\\c_file_demo1.txt");
    FILE *fp = fopen(path, "rt");
    if (!fp) { free(path); return; }

    char ch;
    while ((ch = fgetc(fp)) != EOF) { /* 處理字符 */ }
    rewind(fp);
    char line[32];
    while (fgets(line, sizeof(line), fp)) { /* 處理行 */ }
    fclose(fp);
    free(path);
}

void file_demo3_formatted(const char *root) {
    char *path = str_concat2(root, "\\c_file_demo2.txt");
    FILE *fp = fopen(path, "wt+");
    if (!fp) { free(path); return; }

    fprintf(fp, "%s %d %d\n", "webabcd", 100, 20);  // 寫入 15 字節
    rewind(fp);
    char name[32]; int num, age;
    fscanf(fp, "%s %d %d\n", name, &num, &age);  // 讀回 3 項
    fclose(fp);
    free(path);
}

void file_demo4_binary(const char *root) {
    struct Employee { int num; char name[32]; };
    struct Employee w[2] = {{100, "wanglei"}, {200, "webabcd"}}, r[2];

    char *path = str_concat2(root, "\\c_file_demo3.b");
    FILE *fp = fopen(path, "wb+");
    if (!fp) { free(path); return; }

    fwrite(w, sizeof(struct Employee), 2, fp);  // 寫入 2 個結構體
    rewind(fp);
    fread(r, sizeof(struct Employee), 2, fp);   // 讀回
    fclose(fp);
    free(path);
}

void file_demo5_random_access(const char *root) {
    struct Employee { int num; char name[32]; };
    struct Employee w[2] = {{100, "wanglei"}, {200, "webabcd"}}, r[1];

    char *path = str_concat2(root, "\\c_file_demo4.b");
    FILE *fp = fopen(path, "wb+");
    if (!fp) { free(path); return; }

    fwrite(w, sizeof(struct Employee), 2, fp);
    fseek(fp, sizeof(struct Employee), SEEK_SET);  // 跳過第1個,定位第2個
    fread(r, sizeof(struct Employee), 1, fp);      // 只讀第2個
    // r[0] = {200, "webabcd"}
    fclose(fp);
    free(path);
}

char *demo_cFile(char *rootPath) {
    file_demo1_write_text(rootPath);
    file_demo2_read_text(rootPath);
    file_demo3_formatted(rootPath);
    file_demo4_binary(rootPath);
    file_demo5_random_access(rootPath);
    return str_concat2("演示文件保存路徑:", rootPath);
}

五、錯誤處理鐵律

  1. 每個 fopen 必須檢查 NULL,失敗時讀取 errno (包含 errno.h)。
  2. 讀寫後檢查 ferror(fp),非 0 表示硬件/介質錯誤。
  3. 調用 clearerr(fp) 清除標誌後方可繼續操作。
  4. 嚴格配對 fclose,即使出錯也要關閉 (或用 goto cleanup 模式)。
  5. 二進制模式用 rb/wb,避免 Windows 換行符轉換損壞數據。

六、Windows 特有注意事項

  • 路徑分隔符:\\ 或 / (MSVC 支持正斜槓)。
  • 大文件 (>2GB):使用 _fseeki64/_ftelli64 或 fgetpos/fsetpos。
  • Unicode 路徑:_wfopen(L"path", L"mode") 配合寬字符。
  • 文件共享模式:_fsopen 可指定 _SH_DENYRW 等共享屬性。

掌握文本/二進制模式差異、格式化與塊 I/O 選擇、隨機訪問定位、完整錯誤處理鏈路,是 Windows C 開發者處理持久化數據的基本功。示例代碼涵蓋所有核心場景,可直接作為項目文件模塊基礎。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
類別函數用途
字符 I/Ofgetc/fputc單字符讀寫
fgets/fputs行/字符串讀寫
getc/putc宏版本,可能更快
格式化 I/Ofprintf/fscanf類 printf/scanf,針對文件流
fscanf 返回值成功匹配/賦值的項目數,EOF 表示失敗/結束
fprintf 返回值寫入字符數
二進制塊 I/Ofread/fwritesize * count 字節,返回完成項目數
結構體直接讀寫fwrite(&struct, sizeof(struct), 1, fp)
注意對齊/填充跨平台需打包 (#pragma pack) 或序列化
隨機訪問fseek(fp, offset, origin)origin: SEEK_SET/CUR/END
ftell(fp)返回當前位置 (long)
rewind(fp)等價 fseek(fp, 0, SEEK_SET) + 清除錯誤標誌
fgetpos/fsetpos大文件支持 (fpos_t)
狀態檢查feof/ferror/clearerr檢查結束/錯誤/清除標誌
關閉fclose(fp)刷新緩衝區、釋放資源,返回 0 成功