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

C++ Windows 下 fwrite 讀寫結構體數據前 25 條正常後亂碼:文件模式不匹配修復

     編輯:程式設計綜合問答

問題根因

代碼以 `"ab+"` (二進制追加讀寫) 打開文件寫入,但**讀取時未指定二進制模式** 或文件指針位置錯誤導致讀寫脫節。Windows 文本模式會轉換 `\n`↔`\r\n`,破壞結構體二進制佈局。

修正方案:統一二進制模式

// 寫入
FILE *bookFile = fopen("book", "wb"); // "wb" 覆蓋寫入 / "ab" 追加
// ... fwrite(&book, BOOK_SIZE, 1, bookFile);
fclose(bookFile);

// 讀取
FILE *p = fopen("book", "rb"); // 必須 "rb"
while (fread(&book, BOOK_SIZE, 1, p) == 1) {
    // 處理 book
}
fclose(p);

關鍵點清單

  • [ ] 所有 `fopen` 操作同一文件**必須一致使用 `"b"` 標志** (`wb`/`rb`/`ab`/`r+b`)。
  • [ ] 結構體需 `#pragma pack(1)` 或 `__attribute__((packed))` 消除填充字節,確保跨平台大小一致。
  • [ ] `fseek(fp, 0, SEEK_END)` 後 `ftell` 獲取位置,若文件以文本模式打開,返回值為**邏輯位置**而非物理字節偏移,導致索引錯誤。
  • [ ] Linux 默認無文本/二進制區分,故 Linux 下運行正常。**跨平台代碼必須顯式指定 `"b"`**。< /li>

進階:封裝 RAII 文件類

class BinFile {
    FILE* fp;
public:
    BinFile(const char* path, const char* mode) : fp(fopen(path, mode)) {}
    ~BinFile() { if (fp) fclose(fp); }
    bool write(const void* buf, size_t size, size_t count) {
        return fwrite(buf, size, count, fp) == count;
    }
    bool read(void* buf, size_t size, size_t count) {
        return fread(buf, size, count, fp) == count;
    }
};
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved