首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C 語言 fwrite 更新文件導致數據清空:文件打開模式錯誤分析

     編輯:程式設計綜合問答

在 C 語言實現學生信息管理系統時,調用 updateStudent() 更新記錄導致文件中原有數據全部清空。根因是 fopen(filename, "wb") 以「寫入二進制」模式打開文件,**會截斷文件長度為 0** 隨後寫入,導致原數據丟失。

錯誤代碼

void updateStudent() {
    FILE* fp;
    if ((fp = fopen(filename, "wb")) == NULL) {  // 錯誤:wb 會清空文件
        // ...
    }
    fseek(fp, number * sizeof(Student), 0);
    fwrite(&stu, sizeof(Student), 1, fp);
    fclose(fp);
}

文件模式對比

模式含義文件存在時適用場景
wb寫入二進制截斷為 0創建新文件/完全重寫
ab追加二進制指針在末尾只在末尾添加
rb+ / r+b讀寫二進制保留原內容,指針在開頭隨機讀寫/更新現有記錄
wb+ / w+b讀寫二進制截斷為 0創建新文件並讀寫

修正方案

void updateStudent() {
    FILE* fp = fopen(filename, "rb+");  // 讀寫模式,保留原數據
    if (fp == NULL) {
        // 文件不存在時可嘗試 wb+ 創建,或報錯
        perror("open file failed");
        return;
    }
    fseek(fp, number * sizeof(Student), SEEK_SET);
    // 讀取原記錄(可選,用於顯示/確認)
    fread(&stu, sizeof(Student), 1, fp);
    // 重新定位並寫入新數據
    fseek(fp, number * sizeof(Student), SEEK_SET);
    fwrite(&stu, sizeof(Student), 1, fp);
    fclose(fp);
}

同類問題:deleteStudent()

同樣使用 "wb" 導致清空。正確做法:

  • 用 "rb+" 打開,fseek 定位,寫入「空記錄」(如 ID=0 或標記刪除位)。
  • 或讀取全文件到內存數組,標記刪除後,"wb" 重寫整個文件(數據量小時簡單可行)。

displayAll() 中的 feof 陷阱

while (!feof(fp)) {  // 錯誤:feof 在讀取失敗後才置位
    fread(&stu, sizeof(Student), 1, fp);
    printf(...);  // 會多打印一次末尾垃圾數據
}

正確寫法:

while (fread(&stu, sizeof(Student), 1, fp) == 1) {
    printf(...);
}

總結

  • 隨機更新二進制文件**必須用 rb+**,wb/wb+ 會清空文件。
  • 讀寫操作後檢查返回值,而非依賴 feof。
  • 關鍵操作(增刪改)前建議備份文件。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved