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

C++ 文件操作實戰:二進制讀寫、fread/fwrite/fprintf 詳解與陷阱避坑

     編輯:C++ 入門

C 風格文件 IO 核心函數

函數用途關鍵參數
fread讀取二進制數據塊buffer, size, count, fp
fwrite寫入二進制數據塊buffer, size, count, fp
fprintf格式化文本輸出fp, format, ...
fscanf格式化文本輸入fp, format, ...

關鍵規則與陷阱

  1. 寫入後必須 fclose,否則緩衝區數據可能不落盤;
  2. 讀取後指針自動後移,連續 fread 可順序讀取;
  3. fprintf 返回寫入字節數,不同參數間自動插入空格;
  4. 二進制模式 "wb"/"rb" 避免換行符轉換(Windows 關鍵)。

完整示例:學生信息二進制存取

#include <cstdio>
#include <cstring>

#define SIZE 2
struct Student { char name[10]; int num; int age; char addr[10]; } stu[SIZE];

void save() {
    FILE* fp = fopen("stu_list", "wb");
    if (!fp) { perror("open"); return; }
    for (int i = 0; i < SIZE; ++i) {
        if (fwrite(&stu[i], sizeof(Student), 1, fp) != 1)
            perror("write");
    }
    fclose(fp);
}

void load() {
    FILE* fp = fopen("stu_list", "rb");
    if (!fp) { perror("open"); return; }
    for (int i = 0; i < SIZE; ++i) {
        if (fread(&stu[i], sizeof(Student), 1, fp) != 1)
            perror("read");
    }
    fclose(fp);
}

int main() {
    // 輸入數據
    for (int i = 0; i < SIZE; ++i)
        scanf("%9s %d %d %9s", stu[i].name, &stu[i].num, &stu[i].age, stu[i].addr);
    save();
    load();
    for (int i = 0; i < SIZE; ++i)
        printf("%s %d %d %s\n", stu[i].name, stu[i].num, stu[i].age, stu[i].addr);
}

現代 C++ 替代方案:<fstream>

#include <fstream>
#include <iostream>
#include <vector>

struct Student { std::string name; int num; int age; std::string addr; };

void saveModern(const std::vector& v, const char* file) {
    std::ofstream ofs(file, std::ios::binary);
    for (auto& s : v) {
        // 需自行序列化字符串長度+內容,或用文本/JSON/Protobuf
    }
}

建議:新代碼優先用 std::fstream(RAII、類型安全、異常支持),或成熟序列化庫(cereal, Boost.Serialization, Protobuf, nlohmann/json)。

結語

C 風格文件操作雖底層高效,但易出錯(緩衝、指針、格式化)。理解 fread/fwrite/fprintf 細節對維護舊代碼、嵌入式開發必不可少;現代項目請擁抱 C++ 流與序列化庫。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved