核心誤區
用戶以為「寫字板打開正常、記事本亂碼」是編輯器特性導致,實則**文件本身就是二進制數據**,根本不是文本文件。
代碼真相
struct st { char name[4]; char age[3]; char tel[9]; } s[3];
fwrite(&s[i], sizeof(struct st), 1, fpo); // 直接寫結構體內存映像
這將結構體在內存中的**原始字節序列**寫入文件,包含:
- 字符數組未填滿部分的隨機殘留值(棧內存垃圾數據)。
- 無分隔符、無換行符、無編碼標識。
- 結構體可能因對齊插入填充字節。
為何現象不同?
| 編輯器 | 渲染邏輯 | 表現 |
| 記事本 | 按當前代碼頁 (GBK/UTF-8) 硬解碼字節流 | 高位字節觸發亂碼、不可見字符顯示為空框 |
| 寫字板 | 嘗試檢測 RTF/Unicode,失敗後退化為類似記行為,但對換行符 0x0A/0x0D 容錯更好 | 偶爾能看到可打印字符片段,誤以為「正常」 |
本質上都無法正確還原結構體數據。
正確的文本存儲方案
// 寫入:格式化文本,每行一條記錄,字段用制表符分隔
fprintf(fpo, "%-4s\t%-3s\t%-9s\n", s[i].name, s[i].age, s[i].tel);
// 讀取:按行讀取 + sscanf 解析
char line[100];
while (fgets(line, sizeof(line), fpe)) {
sscanf(line, "%3s\t%2s\t%8s", s[i].name, s[i].age, s[i].tel);
// 處理...
}
若必須用二進制文件
- 統一結構體對齊:
#pragma pack(push, 1) ... #pragma pack(pop)。
- 固定字符串長度,補
\0,避免垃圾數據。
- 讀寫雙方**完全一致**的結構體定義、對齊、字節序(跨平台需處理大小端)。
- 文件頭寫入 Magic Number + 版本號,驗證兼容性。
結論
**不要用記事本/寫字板驗證二進制文件**。用十六進制編輯器 (HxD, 010 Editor) 或自寫 Dump 工具。文本存儲請用格式化 I/O (fprintf/fscanf) 或 JSON/CSV/XML 等結構化格式。
- 上一篇文章: VB6 導出數據到 Excel 兩大方案:CSV 簡易法與 COM 自動化深度解析
- 下一篇文章: Java 註解 與 註釋 深度解析:給機器看 vs 給人看
Copyright ©
程式碼之家 All Rights Reserved