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

C語言結構體讀寫文件實現數據持久化

     編輯:C 語言基礎

前言

在C語言開發中,當需要存儲少量結構化數據時,引入MySQL等重型數據庫顯得過於繁瑣。更輕量的方案是將結構體數據直接以二進制形式寫入文件,需要時再讀取還原。本文通過完整的代碼示例,演示如何實現結構體的文件讀寫操作,並封裝為可復用的函數庫。

核心功能設計

我們定義兩個核心函數:writeStruct 用於將內存中的結構體數據寫入文件,readStruct 用於從文件讀取數據還原到內存。兩者均採用緩衝區指針配合長度參數的方式,可適配任意結構體類型。

頭文件 struct.h

#ifndef STRUCT_H
#define STRUCT_H

#include <stdbool.h>

/**
 * 將結構體數據寫入文件
 * @param fileName 文件名
 * @param buffer 數據緩衝區指針
 * @param bufferLen 緩衝區長度(字節)
 * @param mode 文件打開模式(如 "wb")
 * @return 成功返回 true,失敗返回 false
 */
bool writeStruct(const char *fileName, const void *buffer, size_t bufferLen, const char *mode);

/**
 * 從文件讀取數據到結構體
 * @param fileName 文件名
 * @param buffer 接收緩衝區指針
 * @param bufferLen 緩衝區長度(字節)
 * @param mode 文件打開模式(如 "rb")
 * @return 成功返回 true,失敗返回 false
 */
bool readStruct(const char *fileName, void *buffer, size_t bufferLen, const char *mode);

#endif

源文件 struct.c

#include "struct.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

bool writeStruct(const char *fileName, const void *buffer, size_t bufferLen, const char *mode) {
    FILE *fp = fopen(fileName, mode);
    if (!fp) {
        perror("fopen");
        return false;
    }

    // 確保從文件開頭寫入
    rewind(fp);
    size_t written = fwrite(buffer, 1, bufferLen, fp);
    if (written != bufferLen) {
        perror("fwrite");
        fclose(fp);
        return false;
    }

    fclose(fp);
    return true;
}

bool readStruct(const char *fileName, void *buffer, size_t bufferLen, const char *mode) {
    FILE *fp = fopen(fileName, mode);
    if (!fp) {
        perror("fopen");
        return false;
    }

    rewind(fp);
    // 讀取前清零緩衝區,避免殘留數據
    memset(buffer, 0, bufferLen);
    size_t readCount = fread(buffer, 1, bufferLen, fp);
    if (readCount != bufferLen) {
        // 讀取長度不足可能是文件損壞或結構不匹配
        perror("fread");
        fclose(fp);
        return false;
    }

    fclose(fp);
    return true;
}

使用示例

以下示例演示如何將一個學生信息結構體保存到文件並讀回:

#include "struct.h"
#include <stdio.h>

typedef struct {
    int id;
    char name[32];
    float score;
} Student;

int main() {
    Student stu = {1001, "張三", 92.5f};
    const char *filename = "student.dat";

    // 寫入文件
    if (writeStruct(filename, &stu, sizeof(Student), "wb")) {
        printf("數據寫入成功。\n");
    } else {
        printf("寫入失敗。\n");
        return 1;
    }

    // 讀取文件
    Student readStu = {0};
    if (readStruct(filename, &readStu, sizeof(Student), "rb")) {
        printf("讀取成功:ID=%d, 姓名=%s, 分數=%.1f\n", 
               readStu.id, readStu.name, readStu.score);
    } else {
        printf("讀取失敗。\n");
    }

    return 0;
}

關鍵點解析

  • 二進制模式:使用 "wb" 和 "rb" 避免文本模式下的換行符轉換,確保數據位級一致。
  • 緩衝區長度:調用者必須傳入正確的 sizeof(結構體),否則會導致讀寫越界或數據截斷。
  • 內存對齊:結構體在不同編譯器/平台上的內存佈局可能不同(填充字節),跨平台讀取時需注意結構體打包(#pragma pack)。
  • 錯誤處理:函數返回布爾值,並通過 perror 輸出系統錯誤信息,便於調試。

總結

通過封裝 fwrite/fread 並統一錯誤處理流程,我們獲得了一套簡潔、可復用的結構體持久化方案。這對於配置文件、遊戲存檔、嵌入式設備參數保存等場景極具實用價值。

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