專案開發常需讀取配置文件(如 Eclipse 的 .prefs),採用 key=value 格式。本文參考 Java Properties 類,設計一套純 C 的配置文件讀寫介面,支援初始化、讀取、修改、新增、刪除、列舉鍵值、資源釋放等操作。
#ifndef _PROPERTIES_H
#define _PROPERTIES_H
#ifdef __cplusplus
extern "C" {
#endif
// 初始化環境,成功返回 0
int init(const char *filepath, void **handle);
// 根據 key 獲取 value,找到返回 0
int getValue(void *handle, const char *key, char *value);
// 修改 key 對應的值,成功返回 0
int setValue(void *handle, const char *key, const char *value);
// 新增屬性,成功返回 0
int add(void *handle, const char *key, const char *value);
// 刪除屬性,成功返回 0
int del(void *handle, const char *key);
// 獲取所有 key,成功返回 0
int getKeys(void *handle, char ***keys, int *keyscount);
// 釋放 keys 記憶體
int free_keys(char ***keys, int *keyscount);
// 獲取所有 value,成功返回 0
int getValues(void *handle, char ***values, int *valuescount);
// 釋放 values 記憶體
int free_values(char ***values, int *valuescount);
// 獲取屬性總數
int getCount(void *handle, int *count);
// 釋放環境資源
int release(void **handle);
#ifdef __cplusplus
}
#endif
#endif
#define KEY_SIZE 128
#define VALUE_SIZE 128
#define LINE_BUF_SIZE 256
typedef struct Properties {
char *key;
char *value;
struct Properties *pNext;
} Properties;
typedef struct PROPS_HANDLE {
Properties *pHead; // 鏈表頭節點(哨兵)
char *filepath; // 配置文件路徑
} PROPS_HANDLE;
採用帶頭節點的單向鏈表儲存鍵值對,PROPS_HANDLE 封裝鏈表頭與文件路徑,對外不透明指標 void* 隱藏內部細節。
int init(const char *filepath, void **handle) {
// 參數檢查、記憶體分配、開啟檔案
// 逐行讀取,以 '=' 分割 key/value
// 去除首尾空白,建立節點插入鏈表
// 將 handle 指向 PROPS_HANDLE
}
int getValue(void *handle, const char *key, char *value) {
// 遍歷鏈表比對 key,找到則複製 value 返回
}
int setValue(void *handle, const char *key, const char *value) {
// 找到節點,更新 value,確保以換行符結尾
// 調用 saveConfig 將整個鏈表寫回檔案
}
int add(void *handle, const char *key, const char *value) {
// 若 key 存在則轉為 setValue
// 否則建立新節點插入鏈表尾部,寫入檔案
}
int del(void *handle, const char *key) {
// 遍歷尋找,從鏈表移除節點並釋放記憶體
// 寫入檔案持久化
}
int release(void **handle) {
// 釋放鏈表所有節點的 key/value/節點本身
// 釋放 filepath 與 PROPS_HANDLE 本身
// 置空 handle 防野指標
}
#include
#include "Properties.h"
int main() {
void *handle;
const char *filepath = "./props.txt"; // 需預先建立
int ret = init(filepath, &handle);
if (ret != 0) return 0;
char buf[128];
// 讀取
if (getValue(handle, "host", buf) == 0) printf("host=%s", buf);
// 修改
setValue(handle, "version", "1.2.3");
// 新增
add(handle, "pool_connection_count", "2000");
// 刪除
del(handle, "connectionMax");
// 列舉所有 key
char **keys; int kc;
getKeys(handle, &keys, &kc);
for (int i=0; i
username=root
password=root123456
host=192.168.1.100
port=9090
connectionMax=200
version=1.0

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