简单的配置类

1.类的作用

项目中,可能会需要用到各种各样的配置,比如数据库的host,root,pwd等配置。这些配置的值与代码本身没有关系,为了项目的灵活性和可移植性,可以在项目中写一个配置类

2.配置文件config.ini的格式

##代表注释后面的内容                                                                                                                                                                                               
#中括号内是配置的类型
[mysql]

#每一行代表一个配置
port= 3306

#允许出现空行

host =127.0.0.1

pwd=mdkdkd

#允许出现重复数据,但是后面的数据会覆盖前面的
pwd = 123456

user=root

db=test

#可以配置多组配置
[server]
port=10000
ip=127.0.0.1
id=1

3.写一个XConfig类,可以加载配置和获取配置

#ifndef X_CONFG
#define X_CONFG

#include <map>

class XConfig
{
    private:
        std::map<std::string, std::map<std::string, std::string>> m_config;
    public:
        bool load(std::string strPath);                                                                                                                                                                            
        std::string getConfigValue(std::string strGroupKey, std::string strKey);
};

#endif

4.实现XConfig类

#include "XConfig.h"
#include <iostream>
#include <fstream>
#include <vector>

bool XConfig::load(std::string strPath)
{
    std::ifstream file;
    file.open(strPath);

    std::cout << "-------------------load config begin------------------" << std::endl;
    std::string buf;
    std::vector<std::string> vConfig;
    while(getline(file, buf)) {
        std::string value;
        //将配置的元素拆分成字符串
        for (auto c : buf) {
            if (c == ' ') {
                continue;
            } else if (c == '#') {
                break;
            } else if (c == ']'){
                value += c;
                break;
            } else if (c == '=') {
                vConfig.push_back(value);
                value = '=';
                continue;
            }
            value += c;
        }
        if (value.size() > 0) {
            vConfig.push_back(value);
        }
    }

    int nIndex = 0;
    std::string strGroupKey = "";
    std::string strKey = "";
    while (nIndex < vConfig.size()) {
        auto& strConfig = vConfig[nIndex++];
        //配置组名
        if (strConfig[0] == '[') {
            if (strConfig[strConfig.size() - 1] != ']') {
                std::cout << "config error:" << strConfig << std::endl;
                return false;
            } else {
                strGroupKey = strConfig.substr(1, strConfig.size() - 2);
            }
            continue;
        }
        //配置的值
        if (strConfig[0] == '=') {
            if (strGroupKey.size() == 0 || strKey.size() == 0) {
                std::cout << "config error:" << strConfig << std::endl;
                return false;
            }
            m_config[strGroupKey][strKey] = strConfig.substr(1, strConfig.size() - 1);
            strKey = "";
            continue;
        }
        //配置的名字
        {
            if (strGroupKey.size() == 0) {
                std::cout << "config groupKey empty:" << strConfig << std::endl;
                return false;
            }
            if (strKey.size() != 0) {
                std::cout << "config strKey not empty:" << strConfig << std::endl;
                return false;

            }
            strKey = strConfig;
        }
    }

    file.close();
    
    //打印加载的结果
    for (auto itGroup = m_config.begin(); itGroup != m_config.end(); itGroup++) {
        for (auto it = itGroup->second.begin(); it != itGroup->second.end(); it++) {
            std::cout << "m_config[" << itGroup->first << "][" << it->first << "] = " << it->second << std::endl;
        }
    }
    std::cout << "-------------------load config end------------------" << std::endl;
    return true;
}

std::string XConfig::getConfigValue(std::string strGroupKey, std::string strKey)
{
    auto itGroup = m_config.find(strGroupKey);
    if (itGroup == m_config.end()) {
        return "";
    }
    
    auto it = itGroup->second.find(strKey);
    if (it == itGroup->second.end()) {
        return "";
    }
    return it->second;

}

5.写一个main.cpp调用一下试试效果

#include <iostream>
#include "/usr/local/mysql/include/mysql.h"
#include "../proto/src/User.pb.h"
#include "XConfig.h"

MYSQL g_mysql;

int main(int argc, char** argv)
{
    //加载配置
    XConfig config;
    if (!config.load(argv[1])) {
        return -1;
    }

    //调用配置
    std::string host = config.getConfigValue("mysql", "host");
    std::string user = config.getConfigValue("mysql", "user");
    std::string pwd = config.getConfigValue("mysql", "pwd");
    std::string db = config.getConfigValue("mysql", "db");

    if (!mysql_init(&g_mysql)) {
        std::cout << "mysql_init err" << std::endl;
        return -1;
    }

    if (!mysql_real_connect(&g_mysql, host.c_str(), user.c_str(), pwd.c_str(), db.c_str(), 0, NULL, CLIENT_MULTI_STATEMENTS)) {
        std::cout << "mysql_real_connect err" << std::endl;
        return -1;
    }

    //设置超时时间
    int value = 2;
    mysql_options(&g_mysql, MYSQL_OPT_READ_TIMEOUT, &value);
    mysql_options(&g_mysql, MYSQL_SET_CHARSET_NAME, "utf8");

    User user1;
    user1.set_id(100);
    user1.set_nickname("窑下村吴彦祖");
    std::string str = "";
    user1.SerializeToString(&str);

    User user2;
    user2.ParseFromString(str);

    //insert 
    char sql[128];
    snprintf(sql, sizeof(sql), "insert into user_data(user_id, user_data) value (%d, \'%s\');", user2.id(), str.c_str());
    if (mysql_real_query(&g_mysql,sql,strlen(sql)) != 0) {
        std::cout << "sql err! sql=" << sql << std::endl;
        return false;
    }

    //select
    char sql2[] = "select * from user_data;";
    if (mysql_real_query(&g_mysql,sql2,strlen(sql2)) != 0) {
        std::cout << "sql err! sql=" << sql2 << std::endl;
        return false;
    }
    User user3;
    auto res = mysql_store_result(&g_mysql);
    auto num = mysql_num_rows(res);
    for (int i = 0; i < num; i++) {
        auto row = mysql_fetch_row(res);
        std::cout << "user_id = " << row[0] << " user_data = " << row[1] << std::endl;
        user3.ParseFromString(row[1]);   
    }
    return 0;
}

6.修改run.sh,在./process后面加上配置文件

ulimit -c 10000                                                                                                                                                                                                    
export LD_LIBRARY_PATH=/usr/local/lib/:/usr/local/mysql/lib:
./process config.ini

7.写配置文件config.ini

##代表注释后面的内容                                                                                                                                                                                               
#中括号内是配置的类型
[mysql]

#
port= 3306

host =127.0.0.1

pwd = 123456

user=root

db=test

[server]
port=10000
ip=127.0.0.1
id=1

8.看看执行的结果

9.小结

配置文件是程序不可少的一部分,一个好的配置加载类可以大大提升项目的稳定性,一般来说,特定的配置文件还需要一些复杂的校验逻辑,大家可以根据自己的项目需求,写特定的配置类。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值