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

下面是“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日

相关文章

  • 惠普HP DeskJet2600打印机怎么设置EWS管理员密码?

    下面我将详细讲解“惠普HP DeskJet2600打印机怎么设置EWS管理员密码”的完整攻略。 什么是EWS管理员密码 EWS是Embedded Web Server(嵌入式Web服务器)的缩写,是一种通过Web浏览器访问和管理设备配置的方式。管理员可以使用EWS来配置打印机设置、网络设置、安全设置和其他高级选项。为了保护打印机的安全,通常会设置一个EWS管…

    other 2023年6月27日
    00
  • offsetparent的解释

    offsetParent的解释 在HTML文档中,offsetParent是一个DOM属性,它指向最近的已定位的祖先元素(position不为static)。我们可以使用offsetParent来计算元素的相对位置。 offsetParent的特征 offsetParent的默认值是html元素本身 如果元素的父元素中没有定义position属性或者定义的p…

    其他 2023年3月29日
    00
  • jQuery获取访问者IP地址的方法(基于新浪API与QQ查询接口)

    jQuery获取访问者IP地址的方法(基于新浪API与QQ查询接口) 简介 在本攻略中,我们将使用jQuery来获取访问者的IP地址。我们将使用新浪API和QQ查询接口来获取IP地址的详细信息。 步骤 1. 引入jQuery库 首先,确保你已经引入了jQuery库。你可以通过以下方式引入: <script src=\"https://code…

    other 2023年7月31日
    00
  • net::err_connection_reset报错原因

    net::err_connection_reset报错原因 当你在使用浏览器访问网站时,有时候可能会遇到一些错误,比如常见的net::err_connection_reset错误。这个错误提示意味着浏览器与服务器之间的连接被意外中断,可能是因为以下原因: 原因1:浏览器缓存和Cookie过期 浏览器缓存和Cookie过期会导致浏览器与服务器之间的连接中断。在…

    其他 2023年3月28日
    00
  • 了解nonheap吗?

    了解nonheap吗? 在Java虚拟机中,内存分为堆内存和非堆内存。堆内存用于存储对象实例,而非堆内存用于存储Java虚拟机自身的数据。其中,非堆内存又分为方法区和直接内存。本文将详细讲解nonheap的概念、作用、示例等内容。 nonheap的概念 nonheap是虚拟机中的非堆内存,用于存储Java虚拟机自身的数据。nonheap包括方法区和直接内存两…

    other 2023年5月8日
    00
  • Android应用开发中View绘制的一些优化点解析

    Android应用开发中View绘制的一些优化点解析 在Android应用开发中,View的绘制是一个重要的环节,对于应用的性能和用户体验有着直接的影响。下面将详细讲解一些优化点,以提高View的绘制效率。 1. 使用ViewStub延迟加载视图 在布局中使用ViewStub可以延迟加载视图,避免在初始化时就加载所有的视图。这样可以减少初始布局的复杂度,提高…

    other 2023年8月21日
    00
  • 详解Java的内存模型

    详解Java的内存模型 Java的内存模型定义了Java程序中各种变量的访问规则和内存操作的行为。了解Java的内存模型对于编写高效且正确的多线程程序至关重要。本攻略将详细讲解Java的内存模型,包括内存模型的基本概念、内存间的交互规则以及如何使用volatile和synchronized关键字来保证线程安全。 基本概念 Java的内存模型将内存划分为主内存…

    other 2023年8月2日
    00
  • django基于restframework的CBV封装详解

    Django基于Rest Framework的CBV封装详解 什么是CBV? CBV全称为Class-Based Views,中文名为基于类的视图,是Django框架中的一种视图函数封装方式。与FBV不同,CBV重点是通过类的继承和重载的方式,对通用的视图功能进行封装,提高代码的重用性。 在实际开发中,CBV通常比FBV更加优雅、简洁、易于维护和扩展,因此,…

    other 2023年6月25日
    00
合作推广
合作推广
分享本页
返回顶部