目標格式
path = /etc/wgetrc
launch_on_start = true
# 註解行
模組化設計 (五個檔案)
1. main.c - 入口
#include
#include "read_properties.h"
int main(void) {
char names[100][100], values[100][100];
read_properties("/home/user/test.properties", names, values);
return 0;
}
2. read_properties.h - 介面
void read_properties(char *pathname, char names[100][100], char values[100][100]);
3. read_properties.c - 主邏輯
#include "read_properties.h"
#include
#include
#include "utils.h"
void read_properties(char *pathname, char names[100][100], char values[100][100]) {
FILE *file = fopen(pathname, "r");
if (!file) return;
char line[100];
int i = 0;
while (fgets(line, sizeof(line), file) && i < 100) {
printf("%s", line); // 測試輸出
parseline(line, names[i], values[i]);
i++;
}
fclose(file);
}
4. utils.h - 工具介面
void parseline(char *line, char *name, char *value);
5. utils.c - 解析核心
#include
#include "utils.h"
void parseline(char *line, char *name, char *value) {
int len = strlen(line);
int eq_pos = 0;
char *p = line;
// 尋找 '='
while (*p != '=' && eq_pos < len) { p++; eq_pos++; }
// 複製 key (不含 '=')
strncpy(name, line, eq_pos > 0 ? eq_pos - 1 : 0);
name[eq_pos > 0 ? eq_pos - 1 : 0] = '\0';
// 複製 value (跳過 '=')
p++; // 跳過 '='
strncpy(value, p, len - eq_pos);
value[len - eq_pos] = '\0';
printf("name = %s value = %s\n", name, value);
}
執行結果
path = /etc/wgetrc
name = path value = /etc/wgetrc
launch_on_boot = true
name = launch_on_boot value = true
版本 1.0 既有缺陷與 V2.0 改進規劃
| 問題 | V2.0 解決方案 |
| 固定 100x100 二維陣列,浪費記憶體/易溢位 | 動態分配結構體陣列或鏈表 |
| 未去除 key/value 前後空白 | trim() 處理 |
| 未忽略空行與註解行 (# 或 ! 開頭) | 解析前過濾 |
| 標頭檔無護衛巨集 | 加入 #ifndef READ_PROPERTIES_H |
strncpy 不保證以 \0 結尾 | 手動添加 \0 或用 snprintf |
| 無錯誤碼回傳 | 回傳 int 狀態碼 |
V2.0 介面草案
typedef struct { char *key; char *value; } KV_Pair;
int read_properties(const char *path, KV_Pair **out_pairs, int *out_count);
// 回傳 0 成功,負數錯誤碼;呼叫者負責 free 每個 key/value 及 pairs 陣列
- 上一篇文章: Perl 與 C 進程間通訊:System V 消息隊列完整實戰指南
- 下一篇文章: C 語言正則表達式 (POSIX Regex) 完整指南:API 詳解與 Email 驗證實戰
Copyright ©
程式碼之家 All Rights Reserved