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

C 語言配置文件讀寫庫實現:鍵值對解析、鏈表存儲與增刪改查完整接口

     編輯:關於C語言

專案背景

參考 Java Properties 類設計,實現純 C 語言的配置文件讀寫庫。支援 key=value 格式,提供完整 CRUD 接口、鏈表內存管理、文件持久化、跨平台編譯 (含 C++ 混編護衛)。

核心數據結構


// 單個配置項節點
typedef struct Properties {
    char *key;
    char *value;
    struct Properties *pNext;
} Properties;

// 環境句柄 (不透明指針)
typedef struct PROPS_HANDLE {
    Properties *pHead;      // 虛擬頭節點
    char *filepath;         // 配置文件路徑
} PROPS_HANDLE;

公開接口 (Properties.h)

函數功能返回值
init(filepath, &handle)初始化,解析文件建立鏈表0 成功,非 0 錯誤碼
getValue(handle, key, value)查詢鍵值0 找到,-2 未找到
setValue(handle, key, value)修改現有鍵值並持久化0 成功,-2 鍵不存在
add(handle, key, value)新增鍵值 (存在則轉修改)0 成功
del(handle, key)刪除鍵值並持久化0 成功,-2 鍵不存在
getKeys(handle, &keys, &count)獲取所有鍵 (需調用 free_keys 釋放)0 成功
getValues(handle, &values, &count)獲取所有值 (需調用 free_values 釋放)0 成功
getCount(handle, &count)獲取配置項總數0 成功
release(&handle)釋放所有資源 (鏈表、路徑、句柄)0 成功

關鍵實現細節

1. 文件解析與鏈表構建 (init)

  • 逐行 fgets 讀取,strstr 尋找 = 分隔鍵值
  • trimeSpace 去除首尾空格
  • 虛擬頭節點簡化鏈表操作邏輯
  • 動態分配節點內存 (malloc + strcpy)

2. 原子化持久化 (saveConfig)


static int saveConfig(const char *filepath, Properties *head) {
    FILE *fp = fopen(filepath, "w");
    Properties *p = head->pNext;
    while (p) {
        fprintf(fp, "%s=%s", p->key, p->value); // value 已含換行
        p = p->pNext;
    }
    fclose(fp);
    return 0;
}

注意:setValue/add/del 修改鏈表後立即全量覆寫文件,保證內存與磁盤一致性。生產環境建議寫臨時文件再 rename 替換,實現原子更新。

3. 內存管理嚴謹性

  • release 遞歸釋放鏈表每個節點的 key、value、節點本身、文件路徑、句柄
  • free_keys/free_values 僅釋放指針陣列 (char**),不釋放字串內容 (字串歸鏈表節點所有)
  • 所有輸出指針參數雙重指針 (char***),方便函數修改調用者指針並歸零防野指針

測試用例與結果


// props.txt 初始內容
username=root
password=root123456
host=192.168.1.100
port=9090
connectionMax=200
version=1.0

// main.c 測試流程
init("props.txt", &handle);
getValue(handle, "host", buf);        // 192.168.1.100
setValue(handle, "version", "1.2.3"); // 修改
add(handle, "pool_connection_countxx", "2000"); // 新增
del(handle, "connectionMax");         // 刪除
getKeys(handle, &keys, &count);       // 遍歷所有鍵
getValues(handle, &vals, &count);     // 遍歷所有值
release(&handle);                     // 完整釋放

工程優化建議

  1. 線程安全:加互斥鎖保護鏈表操作
  2. 增量寫入:大文件時全量覆寫開銷大,可改為追加/標記刪除+定期重組
  3. 支援 Section:擴展為 [section] key=value 結構 (類似 INI)
  4. 類型轉換輔助:getInt/getBool/getFloat 封裝 atoi/atof
  5. 錯誤碼細化:區分文件不存在、權限不足、格式錯誤、內存不足等
  6. 單元測試:覆蓋邊界條件 (空值、特殊字符、超長行、編碼問題)

源碼獲取

GitHub: git@github.com:xyang0917/RWAppProperites.git

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