C++读写INI配置文件的类实例

yizhihongxing

下面是“C++读写INI配置文件的类实例”的完整攻略:

一、背景介绍

INI配置文件是一种常见的文本配置文件格式,它使用Section和Key-Value键值对来存储配置信息,广泛应用于各种软件中。在C++开发中,我们可以通过读写INI配置文件的方式来实现软件的配置管理,方便快捷。

二、INI配置文件的基本格式

INI配置文件的基本格式是由Section和Key-Value键值对构成的,具体如下:

[Section1]
Key1=Value1
Key2=Value2

[Section2]
Key3=Value3
Key4=Value4

其中,[Section]表示一个Section节点,它下面的Key=Value对则是该Section节点下面的键值对。

三、实现INI配置文件读写的类

为了方便读写INI配置文件,我们可以封装一个Config类,实现INI配置文件的读写操作。具体实现如下:

1. Config类的定义

#pragma once

#include <string>
#include <map>

class Config {
public:
    Config() = default;

    // 加载INI配置文件
    bool load(const std::string& filename);

    // 保存INI配置文件
    bool save(const std::string& filename);

    // 获取指定Section节点下的指定Key的Value值
    std::string get(const std::string& section, const std::string& key, const std::string& defaultValue = "");

    // 设置指定Section节点下的指定Key的Value值
    void set(const std::string& section, const std::string& key, const std::string& value);

private:
    // 解析INI配置文件
    bool parse();

private:
    std::string m_filename;              // INI配置文件名
    std::map<std::string, std::map<std::string, std::string>> m_data;   // 解析后的数据,使用map存储
};

2. Config类的方法实现

1) load方法

bool Config::load(const std::string& filename) {
    m_filename = filename;
    return parse();
}

load方法用于加载INI配置文件,将配置文件中的数据解析后存储到m_data中。

2) save方法

bool Config::save(const std::string& filename) {
    m_filename = filename;
    std::ofstream file(m_filename);
    if (!file.is_open()) {
        return false;
    }

    for (auto& section : m_data) {
        file << "[" << section.first << "]" << std::endl;
        for (auto& kv : section.second) {
            file << kv.first << "=" << kv.second << std::endl;
        }
        file << std::endl;
    }

    file.close();
    return true;
}

save方法用于保存INI配置文件,将m_data中的数据保存到指定的文件中。

3) get方法

std::string Config::get(const std::string& section, const std::string& key, const std::string& defaultValue) {
    if (m_data.count(section) && m_data[section].count(key)) {
        return m_data[section][key];
    }

    return defaultValue;
}

get方法用于获取指定Section节点下的指定Key的Value值,如果Key不存在则返回默认值。

4) set方法

void Config::set(const std::string& section, const std::string& key, const std::string& value) {
    m_data[section][key] = value;
}

set方法用于设置指定Section节点下的指定Key的Value值,如果Section节点或Key不存在则会创建它们。

5) parse方法

bool Config::parse() {
    std::ifstream file(m_filename);
    if (!file.is_open()) {
        return false;
    }

    m_data.clear();

    std::string line, section;
    while (std::getline(file, line)) {
        line = trim(line);

        // 判断是否为注释行
        if (line.empty() || line[0] == '#' || line[0] == ';') {
            continue;
        }

        // 解析Section节点
        if (line[0] == '[' && line[line.size() - 1] == ']') {
            section = line.substr(1, line.size() - 2);
            continue;
        }

        // 解析Key-Value键值对
        auto pos = line.find('=');
        if (pos == std::string::npos) {
            continue;
        }

        auto key = trim(line.substr(0, pos));
        auto value = trim(line.substr(pos + 1, line.size() - pos - 1));

        m_data[section][key] = value;
    }

    file.close();
    return true;
}

parse方法用于解析INI配置文件,将配置文件中的数据解析后存储到m_data中。

3. Config类的辅助函数

为了方便地对INI配置文件进行解析和处理,我们还可以定义一些辅助函数。

1) trim函数

std::string trim(const std::string& str) {
    std::string result = str;
    auto pos = result.find_first_not_of(" \t\r\n");
    if (pos == std::string::npos) {
        return "";
    }
    result.erase(0, pos);
    pos = result.find_last_not_of(" \t\r\n");
    if (pos != std::string::npos) {
        result.erase(pos + 1);
    }
    return result;
}

trim函数用于去掉字符串前后的空格、制表符和换行符等空白符号。

四、实例说明

以下是两条示例说明,分别演示Config类的读写INI配置文件的基本用法。

1. 示例:读取INI配置文件

假设我们有一个配置文件config.ini,它的内容如下:

[Database]
host=127.0.0.1
port=3306
user=root
password=123456
dbname=testdb

我们可以使用以下代码读取该配置文件的内容:

#include <iostream>
#include "Config.hpp"

int main() {
    Config config;
    if (!config.load("config.ini")) {
        std::cout << "Load config file failed." << std::endl;
        return -1;
    }

    auto host = config.get("Database", "host", "localhost");
    auto port = config.get("Database", "port", "3306");
    auto user = config.get("Database", "user", "");
    auto password = config.get("Database", "password", "");
    auto dbname = config.get("Database", "dbname", "");

    std::cout << "Host: " << host << std::endl;
    std::cout << "Port: " << port << std::endl;
    std::cout << "User: " << user << std::endl;
    std::cout << "Password: " << password << std::endl;
    std::cout << "DBName: " << dbname << std::endl;

    return 0;
}

运行上面的代码,输出结果如下:

Host: 127.0.0.1
Port: 3306
User: root
Password: 123456
DBName: testdb

可以看到,我们成功从配置文件读取到了相应的配置信息。

2. 示例:写入INI配置文件

同样假设我们有一个配置文件config.ini,它的内容如下:

[Database]
host=localhost
port=3306
user=root
password=123456
dbname=testdb

我们可以使用以下代码修改该配置文件中的内容:

#include <iostream>
#include "Config.hpp"

int main() {
    Config config;
    if (!config.load("config.ini")) {
        std::cout << "Load config file failed." << std::endl;
        return -1;
    }

    config.set("Database", "host", "127.0.0.1");
    config.set("Database", "port", "8888");
    config.set("Database", "user", "admin");
    config.set("Database", "password", "654321");

    if (!config.save("config.ini")) {
        std::cout << "Save config file failed." << std::endl;
        return -1;
    }

    return 0;
}

运行上面的代码后,我们可以看到配置文件config.ini中的内容已经被修改为以下内容:

[Database]
host=127.0.0.1
port=8888
user=admin
password=654321
dbname=testdb

可以看到,我们成功地通过Config类实现了INI配置文件的读写操作。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++读写INI配置文件的类实例 - Python技术站

(0)
上一篇 2023年6月25日
下一篇 2023年6月25日

相关文章

  • matlabr2016b安装教程

    Matlab R2016b安装教程的完整攻略 本文将提供一份关于Matlab R2016b安装教程的完整攻略,包括下载、安装、激活以及注意事项。 下载 先需要从MathWorks官网下载Matlab R2016b安装文件。可以通过以下步骤进行下载: 访问MathWorks官网:https://www.mathworks/ 点击“Downloads”按钮,进入…

    other 2023年5月9日
    00
  • C++类成员构造函数和析构函数顺序示例详细讲解

    C++中类成员的构造函数和析构函数顺序是一个重要的问题。理解正确的顺序可以避免代码出现意外的问题。在这里,我们会详细讲解C++类成员构造函数和析构函数顺序的相关知识。 构造函数和析构函数的顺序 C++中类成员的构造函数和析构函数的顺序如下: 首先,会调用基类的构造函数(如果有的话)。 然后,会调用成员变量的构造函数(按照它们在类中的声明顺序调用)。 最后,调…

    other 2023年6月26日
    00
  • Mybatis resultMap标签继承、复用、嵌套方式

    MyBatis resultMap标签继承、复用、嵌套方式攻略 MyBatis是一个流行的Java持久化框架,它提供了许多强大的功能来简化数据库操作。其中,resultMap标签是一个重要的元素,用于将查询结果映射到Java对象。在本攻略中,我们将详细讲解MyBatis resultMap标签的继承、复用和嵌套方式。 继承方式 使用继承方式可以减少重复的代码…

    other 2023年7月28日
    00
  • C语言中static与sizeof查缺补漏篇

    C语言中static与sizeof查缺补漏篇 static关键字 在C语言中,static是一个关键字,用于声明静态变量和静态函数。静态变量和静态函数具有以下特点: 静态变量:静态变量在程序的整个生命周期内都存在,不会因为函数的调用而被销毁。它们在内存中的位置固定,只会被初始化一次。静态变量默认情况下具有文件作用域,即只能在声明它的文件中访问。 示例1:静态…

    other 2023年7月29日
    00
  • 百度开发者工具怎么使用?百度开发者工具使用教程与常见问题

    百度开发者工具怎么使用? 百度开发者工具是一款专门为开发者设计的浏览器插件,可以帮助开发者更方便地调试和优化代码,提高开发效率。在使用百度开发者工具之前,我们先来了解一下它的使用方法和常见问题。 百度开发者工具使用教程 以下是百度开发者工具使用教程的具体步骤: 步骤1:下载和安装百度开发者工具 首先打开 Chrome 浏览器,在 Chrome 商店中搜索百度…

    other 2023年6月26日
    00
  • 新手入门必看:InDesign最常见问题22例整理大全

    新手入门必看:InDesign最常见问题22例整理大全攻略 1. 什么是InDesign? InDesign是一款由Adobe开发的专业排版软件,广泛用于制作印刷品、电子出版物和交互式文档。 2. 如何创建新文档? 要创建新文档,请按照以下步骤操作:- 打开InDesign软件。- 在菜单栏中选择“文件”>“新建”>“文档”。- 在弹出的对话框中…

    other 2023年8月5日
    00
  • vue混入mixin流程与优缺点详解

    Vue混入mixin流程与优缺点详解 1. 什么是Vue混入mixin? Vue混入mixin指的是一种Vue的组件复用方式,即将一段共用逻辑代码抽象出来,再通过混入的形式注入到Vue的多个实例中。 2. Vue混入mixin的流程 Vue混入mixin的具体流程如下: 定义混入对象:在Vue中,通过Vue.mixin()方法定义混入对象,该方法接收一个包含…

    other 2023年6月27日
    00
  • python正则表达式使用字符串变量

    Python正则表达式使用字符串变量 正则表达式是一种用于字符串匹配和搜索的工具,通过特定的符号和语法规则,我们可以实现对于不同格式的文本的有效提取和匹配。Python是一种流行的编程语言,在Python代码中,我们可以使用正则表达式模块re来实现对于字符串的正则匹配。 有时候,在我们使用正则表达式的过程中,我们可能需要用到一些字符串变量,以便更加灵活地处理…

    其他 2023年3月29日
    00
合作推广
合作推广
分享本页
返回顶部