結構:[section] + key=value,適合簡單配置。
https://github.com/benhoyt/inih// config.ini
[server]
port = 8080
host = "0.0.0.0"
[database]
url = "postgres://user:pass@localhost/db"
#define INI_MAX_LINE 200
#include "ini.h"
typedef struct { int port; const char *host; const char *db_url; } Config;
int handler(void *user, const char *section, const char *name, const char *value) {
Config *c = (Config*)user;
if (strcmp(section, "server") == 0) {
if (strcmp(name, "port") == 0) c->port = atoi(value);
else if (strcmp(name, "host") == 0) c->host = strdup(value);
} else if (strcmp(section, "database") == 0) {
if (strcmp(name, "url") == 0) c->db_url = strdup(value);
}
return 1;
}
int main() {
Config cfg = {0};
if (ini_parse("config.ini", handler, &cfg) < 0) {
fprintf(stderr, "Parse failed\n");
return 1;
}
printf("Port: %d, Host: %s, DB: %s\n", cfg.port, cfg.host, cfg.db_url);
return 0;
}
適合複雜文檔、資料交換、文書標記。
apt-get install libxml2-dev / yum install libxml2-devel#include#include #include int main() { xmlDoc *doc = xmlReadFile("data.xml", NULL, 0); if (!doc) return 1; xmlNode *root = xmlDocGetRootElement(doc); for (xmlNode *cur = root->children; cur; cur = cur->next) { if (cur->type == XML_ELEMENT_NODE && xmlStrcmp(cur->name, (xmlChar*)"item") == 0) { xmlChar *name = xmlGetProp(cur, (xmlChar*)"name"); xmlChar *content = xmlNodeGetContent(cur); printf("Item: %s = %s\n", name, content); xmlFree(name); xmlFree(content); } } xmlFreeDoc(doc); xmlCleanupParser(); return 0; }
static void startElement(void *ctx, const xmlChar *name, const xmlChar **atts) {
if (xmlStrcmp(name, (xmlChar*)"item") == 0) {
for (int i = 0; atts[i]; i += 2)
printf(" %s='%s'", atts[i], atts[i+1]);
puts("");
}
}
int main() {
xmlSAXHandler sax = {0};
sax.startElement = startElement;
xmlSAXUserParseFile(&sax, NULL, "large.xml");
xmlCleanupParser();
return 0;
}
適合複雜配置、CI/CD 流程定義 (GitHub Actions, GitLab CI)、Kubernetes 資源清單。
apt-get install libyaml-dev#include#include #include int main() { FILE *fh = fopen("config.yaml", "r"); yaml_parser_t parser; yaml_event_t event; yaml_parser_initialize(&parser); yaml_parser_set_input_file(&parser, fh); while (yaml_parser_parse(&parser, &event)) { switch (event.type) { case YAML_SCALAR_EVENT: printf("Scalar: %s\n", event.data.scalar.value); break; case YAML_MAPPING_START_EVENT: puts("Mapping start"); break; case YAML_SEQUENCE_START_EVENT: puts("Sequence start"); break; default: break; } yaml_event_delete(&event); } yaml_parser_delete(&parser); fclose(fh); return 0; }
| 需求 | 推薦格式 | 推薦庫 |
|---|---|---|
| 極簡配置、嵌入式、零依賴 | INI | inih (單頭檔) |
| 結構化資料、需 Schema 驗證、XPath 查詢 | XML | libxml2 (完整功能) / expat (串流) |
| 人類可讀配置、巢狀結構、CI/CD、K8s | YAML | libyaml (C) / yaml-cpp (C++) |
| 高效能序列化、二進位、跨語言 | Protobuf/MessagePack | protobuf-c / msgpack-c |
| 記憶體極受限、單向解析 | XML/JSON | expat / jsmn (JSON) |
xmlSetExternalEntityLoader(NULL) 或 XML_PARSE_NOENT 關閉。