c++常见配置文件格式 JSON、INI、XML、YAML 它们如何解析

1. INI 格式(最简单、Windows 原生)

示例 config.ini

ini

复制代码
[Server]
IP = 127.0.0.1
Port = 8080
MaxConn = 100

[App]
Name = MyServer
Version = 1.0.0

C++ 解析(Windows 原生 API,无需库)

cpp

运行

cpp 复制代码
windows:
-------------------------------------------
#include <Windows.h>

int main() {
    char ip[32] = {0};
    char port[16] = {0};

    // 读取
    GetPrivateProfileStringA("Server", "IP", "", ip, 32, "./config.ini");
    GetPrivateProfileStringA("Server", "Port", "", port, 16, "./config.ini");

    int portNum = atoi(port);
    return 0;
}

linux 
-------------------------------------------
/*   删除右边的空格   */
char *r_trim(char *szOutput, const char *szInput)
{
    char *p = NULL;
    assert(szInput != NULL);
    assert(szOutput != NULL);
    assert(szOutput != szInput);
    strcpy(szOutput, szInput);
    for(p = szOutput + strlen(szOutput) - 1; p >= szOutput && isspace(*p); --p)
    {
        ;
    }
    *(++p) = '\0';
    return szOutput;
}

/*   删除两边的空格   */
char * a_trim(char * szOutput, const char * szInput)
{
    char *p = NULL;
    assert(szInput != NULL);
    assert(szOutput != NULL);
    l_trim(szOutput, szInput);
    for   (p = szOutput + strlen(szOutput) - 1; p >= szOutput && isspace(*p); --p)
    {
        ;
    }
    *(++p) = '\0';
    return szOutput;
}
//获取配置文件项信息
int GetProfileString(const char *profile, const char *AppName, const char *KeyName, char *KeyVal, const char *oVal)
{
    char appname[32], keyname[32];

    char *buf, *c;
    char buf_i[KEYVALLEN], buf_o[KEYVALLEN];
    memcpy(KeyVal, oVal, strlen(oVal) + 1);
    FILE *fp;
    int found = 0; /* 1 AppName 2 KeyName */
    if ((fp = fopen(profile, "r")) == NULL)
    {
        if(g_iLogLevel & 1)
            printf("openfile [%s] error [%s]", profile, strerror(errno));
        return(-1);
    }
    fseek(fp, 0, SEEK_SET);
    memset(appname, 0, sizeof(appname));
    sprintf(appname, "[%s]", AppName);

    while (!feof(fp) && fgets(buf_i, KEYVALLEN, fp) != NULL)
    {
        l_trim(buf_o, buf_i);
        if (strlen(buf_o) <= 0)
            continue;
        buf = NULL;
        buf = buf_o;

        if (found == 0)
        {
            if (buf[0] != '[')
            {
                continue;
            }
            else if (strncmp(buf, appname, strlen(appname)) == 0)
            {
                found = 1;
                continue;
            }

        }
        else if (found == 1)
        {
            if (buf[0] == '#')
            {
                continue;
            }
            else if (buf[0] == '[')
            {
                break;
            }
            else
            {
                if ((c = (char*)strchr(buf, '=')) == NULL)
                    continue;
                memset(keyname, 0, sizeof(keyname));

                sscanf(buf, "%[^=|^ |^\t]", keyname);
                if (strcmp(keyname, KeyName) == 0)
                {
                    sscanf(++c, "%[^\n]", KeyVal);
                    char *KeyVal_o = (char *)malloc(strlen(KeyVal) + 1);
                    if (KeyVal_o != NULL)
                    {
                        memset(KeyVal_o, 0, strlen(KeyVal) + 1);
                        a_trim(KeyVal_o, KeyVal);
                        if (KeyVal_o && strlen(KeyVal_o) > 0)
                            strcpy(KeyVal, KeyVal_o);
                        free(KeyVal_o);
                        KeyVal_o = NULL;
                    }
                    found = 2;
                    break;
                }
                else
                {
                    continue;
                }
            }
        }
    }
    fclose(fp);
    if (found == 2)
        return(0);
    else
        return(-1);
}

优点

  • 最简单、开箱即用
  • Windows 原生 API,不需要任何第三方库
  • 轻量、人眼易读

缺点

  • 不支持嵌套、不支持数组
  • 仅适合简单配置

2. JSON(最通用、前后端通用)

示例 config.json

json

复制代码
{
    "Server": {
        "IP": "127.0.0.1",
        "Port": 8080,
        "MaxConn": 100
    },
    "App": {
        "Name": "MyServer",
        "Version": "1.0.0"
    }
}

C++ 解析(用 nlohmann/json,单头文件神器)

cpp

运行

复制代码
#include "nlohmann/json.hpp"
#include <fstream>
using json = nlohmann::json;

int main() {
    std::ifstream f("config.json");
    json data = json::parse(f);

    std::string ip = data["Server"]["IP"];
    int port = data["Server"]["Port"];
    std::string name = data["App"]["Name"];

    return 0;
}

优点

  • 几乎所有语言支持
  • 支持对象、数组、嵌套
  • 现代配置首选

缺点

  • 不能写注释(标准不支持)

3. XML(老式、偏重量级)

示例 config.xml

xml

复制代码
<Config>
    <Server>
        <IP>127.0.0.1</IP>
        <Port>8080</Port>
    </Server>
</Config>

C++ 解析(用 tinyxml2

cpp

运行

复制代码
#include "tinyxml2.h"
using namespace tinyxml2;

int main() {
    XMLDocument doc;
    doc.LoadFile("config.xml");

    XMLElement* server = doc.FirstChildElement("Config")->FirstChildElement("Server");
    const char* ip = server->FirstChildElement("IP")->GetText();

    return 0;
}

优点

  • 结构化强、可扩展
  • 企业 / 旧项目常用

缺点

  • 臃肿、标签冗余
  • 阅读麻烦、解析代码长

4. YAML(最优雅、可读性最高)

示例 config.yaml

yaml

复制代码
Server:
  IP: 127.0.0.1
  Port: 8080
  MaxConn: 100

App:
  Name: MyServer
  Version: 1.0.0

C++ 解析(用 yaml-cpp

cpp

运行

复制代码
#include <yaml-cpp/yaml.h>

int main() {
    YAML::Node config = YAML::LoadFile("config.yaml");

    std::string ip = config["Server"]["IP"].as<std::string>();
    int port = config["Server"]["Port"].as<int>();

    return 0;
}

优点

  • 人类友好,最干净
  • 支持注释、嵌套、数组
  • DevOps / 云原生 主流

缺点

  • 缩进敏感(像 Python)
  • C++ 库比 JSON 稍大

🚀 最终推荐

1. 最简单 → INI

2. 通用全能 → JSON(最推荐)

3. 优雅高级 → YAML

4. 老式企业项目 → XML

相关推荐
Elieal2 小时前
java基础面试
java·开发语言·面试
C++chaofan2 小时前
RPC框架容错机制深度解析
java·开发语言·后端·性能优化·高并发·juc·容错机制
2301_795741792 小时前
在构建企业级文生视频存储架构时,RustFS相比传统存储方案有哪些独特优势?
开发语言·python·pygame
是娇娇公主~2 小时前
C++ 中 std::vector 和 std::list 的区别
开发语言·c++·list
镜中月ss2 小时前
QT中的资源树
开发语言·qt·qml
小陈工2 小时前
2026年3月25日技术资讯洞察:开源芯片革命、Postgres文件系统与AI Agent安全新范式
开发语言·数据库·人工智能·python·安全·web安全·开源
C++chaofan2 小时前
RPC框架负载均衡机制深度解析
java·开发语言·负载均衡·juc·synchronized·
Laurence2 小时前
GitHub 1.2 万星 Qt 项目 VNote 源码解读(一):核心类与主流程
qt·github·源码·代码·介绍·解读·vnote
飞Link2 小时前
Python `warnings` 库底层机制全解析与企业级 API 演进实战
开发语言·python