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

C語言二進制文件為什麼記事本打不開?文本 vs 二進制模式深度解析

     編輯:C 語言問答

現象

用 fwrite 寫入結構體數組,返回值正確,但用記事本打開顯示亂碼或空白。

根本原因:二進制文件 ≠ 文本文件

維度文本文件 (Text Mode)二進制文件 (Binary Mode)
存儲內容字符編碼(ASCII/UTF-8/GBK),人類可讀內存原始位模式,機器可讀
換行符Windows: \r\n ↔ \n 自動轉換**無任何轉換**,原樣讀寫
EOF 標記可能有 Ctrl+Z (0x1A) 作為文件結束無特殊標記,按字節數讀寫
典型用途配置文件、日誌、源碼、CSV圖片、視頻、數據庫、序列化結構體、緩存
打開方式fopen("file.txt", "r/w")fopen("file.bin", "rb/wb") **關鍵加 b**

為什麼記事本顯示亂碼?

struct Student { int id; char name[20]; float score; };
struct Student s = {2023001, "Zhang", 92.5};
fwrite(&s, sizeof(s), 1, fp);

記事本嘗試將每個字節解釋為字符編碼:
id 的 4 字節 0xE8 0x76 0x1E 0x00 → 顯示為亂碼「èv..」
name 部分可讀「Zhang\0\0...」
score 的 4 字節 IEEE 754 0x00 0x48 0xC7 0x42 → 亂碼
**結論:二進制文件必須用對應結構體讀回,或用十六進制編輯器查看。**

正確查看二進制文件的工具

  • 十六進制編輯器:HxD (Win)、Hex Fiend (Mac)、Ghex (Linux)、xxd/hexdump -C (命令行)。
  • 程序化讀回:
    struct Student s;
    fread(&s, sizeof(s), 1, fp);
    printf("id=%d name=%s score=%.1f\n", s.id, s.name, s.score);
  • 調試器內存窗口:VS Code / GDB x/32xb &s。

文本模式寫入對比

// 文本模式:人類可讀,但解析慢、佔空間、精度損失
fprintf(fp, "%d %s %.2f\n", s.id, s.name, s.score);
// 輸出:2023001 Zhang 92.50

// 二進制模式:機器高效,精度完美、體積小、不可直接閱讀
fwrite(&s, sizeof(s), 1, fp);

跨平台陷阱:結構體對齊與端序

// 不同編譯器/架構下 sizeof(Student) 可能不同(對齊填充)
// 不同 CPU 端序導致整數/浮點數字節序不同(大端 vs 小端)

// 解決方案:序列化協議
// 1. 固定長度字符串 + 手動打包(網絡字節序 htonl/ntohl)
// 2. Protocol Buffers / FlatBuffers / MessagePack
// 3. 自定義文本格式(JSON/TOML/CSV)犧牲性能換可移植

總結

  • fwrite/fread 產出/讀取 **二進制文件**,記事本**無法正確解讀**。
  • 查看二進制文件:**用十六進制編輯器**,或**寫程序按結構體讀回**。
  • 需人類可讀:**改用 fprintf/fscanf 文本模式**,或序列化為 JSON。
  • 跨平台持久化:**避免直接傳結構體**,採用標準序列化協議。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved