共享单车(一):项目配置

配置文件

对于很多程序中要用的参数如果是可变的,那么最好的处理方式就是通过main函数参数传递,或者从别的地方去获取,这其中之一就是配置文件,但是在一个成熟和架构完善的系统,一般都会做到自动配置,自动部署,所以有的系统里会有一个单独的配置服务存在,每个其它的服务的配置信息从配置中心服务获取,然后运维人员通过操作界面把配置信息下发给配置中心服务,其余服务从配置中心获取变更信息。

共享单车配置文件:

[database]
ip       = 127.0.0.1 ;
port     = 3306 ;
user     = root ;
pwd      = 123456 ;
db       = qiniubike;

[server]
port     = 9090;

ini 的配置文件:[database] 就是我们的俗称的区段,ip,port就是字段,127.0.0.1和3306就是字段的值

加载配置文件

读取文件内容,然后依照文件内容,把这些字段和值组成key-value的形式保存在某个数据结构中,这样通过key(区段+字段)就能找到value(值)

ini 文件格式:

节 
    [section]  

参数(键=值) 
    name=value

注解 
    注解使用分号表示(;)。在分号后面的文字,直到该行结尾都全部为注解。

iniparser 的一条原则是 section 和 key 大小写无关,写入的字符串全部小写化,取出的字符串也全部小写化。

iniparser 下载地址:https://github.com/ndevilla/iniparser

使用方法方法1:

拷贝 src 下的头文件 dictionary.h 和 iniparser.h 到系统目录下,/usr/include 或 /usr/local/include.
拷贝压缩包目录下的静态库 libiniparser.a 和动态库 libiniparser.so.1 到目标文件系统的对应目录下,/usr/lib 或 lib/

使用方法方法2:
直接将 src 下的 dictionary.c,iniparser.c,dictionary.h 和 iniparser.h 到项目目录下,在 makefile 里编译 dictionary.c,iniparser.c,使用时调用头文件就行。

Iniparser库详解

创建配置文件结构体

文件:configdef.h

#include <iostream>
#include "iniconfig.h"
#include <iniparser/iniparser.h>


Iniconfig::Iniconfig():_isloaded(false){

}

Iniconfig::~Iniconfig(){

}

bool Iniconfig::loadfile(const std::string& path){
    dictionary* ini = NULL;

    if(!_isloaded){

        ini = iniparser_load(path.c_str());


        if (ini == NULL) {
            fprintf(stderr, "cannot parse file: %s\n", path.c_str());
            return false ;
        }
        /*
        [database]
        ip       = 127.0.0.1 ;
        port     = 3306 ;
        user     = root ;
        pwd      = 123456 ;
        db       = qiniubike;


        [server]
        port     = 9090;
        */
        // The third parameter is a candidate parameter
        const char* ip = iniparser_getstring(ini, "database:ip","127.0.0.1");
        int   port  = iniparser_getint(ini, "database:port", 3306);
        const char* user  = iniparser_getstring(ini, "database:user", "root");
        const char* pwd   = iniparser_getstring(ini, "database:pwd", "123456");
        const char* db    = iniparser_getstring(ini, "database:db", "dongnaobike");
        int   sport = iniparser_getint(ini, "server:port", 9090);

        _config = st_env_config(std::string(ip), port, std::string(user), \
            std::string(pwd), std::string(db), sport);

        iniparser_freedict(ini);

        _isloaded = true;


    }
        
    return _isloaded;

}

const st_env_config& Iniconfig::getconfig(){
    return _config;
}

将获取配置信息和初始化配置信息 封装成类

文件:iniconfig.h

#ifndef SHBK_COMMON_INICONFIG_H_
#define SHBK_COMMON_INICONFIG_H_

#include <string>
#include "configdef.h"


class Iniconfig
{
public:
    Iniconfig();
    ~Iniconfig();
    bool loadfile(const std::string& path);
    const st_env_config& getconfig();

private:
    st_env_config _config;
    bool _isloaded;

};



#endif // !SHBK_COMMON_INICONFIG_H_

文件:iniconfig.cpp

#include <iostream>
#include "iniconfig.h"
#include <iniparser/iniparser.h>


Iniconfig::Iniconfig():_isloaded(false){

}

Iniconfig::~Iniconfig(){

}

bool Iniconfig::loadfile(const std::string& path){
    dictionary* ini = NULL;

    if(!_isloaded){

        ini = iniparser_load(path.c_str());


        if (ini == NULL) {
            fprintf(stderr, "cannot parse file: %s\n", path.c_str());
            return false ;
        }
        /*
        [database]
        ip       = 127.0.0.1 ;
        port     = 3306 ;
        user     = root ;
        pwd      = 123456 ;
        db       = qiniubike;


        [server]
        port     = 9090;
        */
        // The third parameter is a candidate parameter
        const char* ip = iniparser_getstring(ini, "database:ip","127.0.0.1");
        int   port  = iniparser_getint(ini, "database:port", 3306);
        const char* user  = iniparser_getstring(ini, "database:user", "root");
        const char* pwd   = iniparser_getstring(ini, "database:pwd", "123456");
        const char* db    = iniparser_getstring(ini, "database:db", "dongnaobike");
        int   sport = iniparser_getint(ini, "server:port", 9090);

        _config = st_env_config(std::string(ip), port, std::string(user), \
            std::string(pwd), std::string(db), sport);

        iniparser_freedict(ini);

        _isloaded = true;


    }
        
    return _isloaded;

}

const st_env_config& Iniconfig::getconfig(){
    return _config;
}

读取配置信息

文件:main.cpp

#include <iostream>
#include "iniconfig.h"
#include "configdef.h"


//shared_bike.exe conf/shared_bike.ini
int main(int argc, char const *argv[]){
    if(argc !=2){
        std::cout <<"Please input shared_bike <config file path>!"<<std::endl;
        return -1;
    }

    Iniconfig config;
    if(!config.loadfile(std::string(argv[1]))){
        std::cout <<"Load "<< argv[1] << "failed!" << std::endl;
        return -2;
    }

    st_env_config conf_args = config.getconfig();

    std::cout <<"[database] ip: "<<conf_args.db_ip.c_str()<<std::endl;
    std::cout <<"[database] port: "<<conf_args.db_port<<std::endl;
    std::cout <<"[database] user: "<<conf_args.db_user.c_str()<<std::endl;
    std::cout <<"[database] pwd: "<<conf_args.db_pwd.c_str()<<std::endl;

    std::cout <<"[server] port: "<<conf_args.svr_port<<std::endl;
    
    return 0;
}

编译

文件:src/common/CMakeLists.txt

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)

# 搜集所有在指定路径下的源文件的文件名,将输出结果列表储存在指定的变量中
aux_source_directory(. SOURCE_COMMON_FILES)

# add_ 1 ibrary (<name>[ STATIC | SHARED |MODULE] [ EXCLUDE_FROM_ALL] sourcel [source2...])
# 构建库供他人模块使用
ADD_LIBRARY(common ${SOURCE_COMMON_FILES})

# 用来显式的定义变量
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -rdynamic -Wall -m64 -pipe -std=c++0x -lrt -Wno-reorder -Wdeprecated-declarations")

# 将指定目录添加到编译器的头文件搜索路径之下
INCLUDE_DIRECTORIES(../../third/include)

# 将指定目录添加到需要链接的库文件目录之下
LINK_DIRECTORIES(../../third/lib/iniparser)

# 该指令的作用为将目标文件与库文件进行链接
TARGET_LINK_LIBRARIES(common iniparser)
TARGET_LINK_LIBRARIES(common dl)

文件:src/CMakeLists.txt

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)

# project name
PROJECT(shared_bike)

# 将指定目录添加到编译器的头文件搜索路径之下
INCLUDE_DIRECTORIES(../third/include)
INCLUDE_DIRECTORIES(./common)

# 将指定目录添加到需要链接的库文件目录之下
LINK_DIRECTORIES(../third/lib/iniparser)
LINK_DIRECTORIES(./common)

# 搜集所有在指定路径下的源文件的文件名,将输出结果列表储存在指定的变量中
# 内置变量: CMAKE_SOURCE_DIR 定义了顶级 CMakeLists.txt 所在的文件夹,PROJECT_SOURCE_DIR 定义了包含最近的 project() 命令的 CMakeLists.txt 所在的文件夹
aux_source_directory(${PROJECT_SOURCE_DIR} SOURCE_FILES)

# 使用给定的源文件,为工程引入一个可执行文件
ADD_EXECUTABLE(shared_bike ${SOURCE_FILES})

# 用来显式的定义变量
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -rdynamic -Wall -m64 -pipe -std=c++0x -lrt -Wno-reorder -Wdeprecated-declarations")

TARGET_LINK_LIBRARIES(shared_bike iniparser)
TARGET_LINK_LIBRARIES(shared_bike common)

# 增加子目录
ADD_SUBDIRECTORY(common)

SET(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR})
INSTALL(TARGETS shared_bike DESTINATION bin)

执行

运行结果:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/568193.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【刷题】前缀和入门

送给大家一句话&#xff1a; 既然已经做出了选择&#xff0c;最好还是先假定自己是对的。焦虑未来和后悔过去&#xff0c;只经历一个就够了。 – 张寒寺 《不正常人类症候群》 ☆ミヾ(∇≦((ヾ(≧∇≦)〃))≧∇)ノ彡☆ ☆ミヾ(∇≦((ヾ(≧∇≦)〃))≧∇)ノ彡☆ ☆ミヾ(∇≦((ヾ…

算法练习第17天|104.二叉树的最大深度 、559.N叉树的最大深度

104.二叉树的最大深度 104. 二叉树的最大深度 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/maximum-depth-of-binary-tree/description/ 什么是二叉树的深度和高度&#xff1f; 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。最大深度…

C语言 三目运算符

C语言 逻辑分支语句中 还有一种 三目运算符 我们编写代码如下 #include <stdio.h>int main() {const char* a 1 1 ? "表达式1" : "表达式2";printf("%s", a);return 0; }这里 我们根据逻辑 先定义一个a 然后 它的值 等于一个 三目运算…

AIGC时代之 - 怎样更好的利用AI助手 - 指令工程

爆火的AIGC 2022年11月30日&#xff0c;OpenAI发布ChatGPT 3 2022年12月4 日&#xff0c;ChatGPT 3 已拥有超过一百万用户 2023年各种大语言模型开始火爆全球 GPT们&#xff0c;已经成为了我工作和学习的非常重要的工具。 ChatGPT也没那么神奇&#xff1f; 不知道大家有没有…

web--验证码识别,找回密码

验证码前端回显 当我不知道验证码 查看数据包就可以知道验证吗在数据包之中 burp爆破 &#xff08;前提是没有次数限制&#xff09; 更改返回数据 将成功的回显值更改 验证码更改脚本&#xff08;智能识别&#xff09; 错误的&#xff1a;只要输入一次对了&#xff0c;在bp…

OFDM-OCDM雷达通信一体化信号模糊函数对比研究【附MATLAB代码】

文章来源&#xff1a;微信公众号&#xff1a;EW Frontier 1.引言 为提高频谱利用率并实现系统小型化、集成化,近年来雷达通信一体化系统成为重要研究方向。正交线性调频波分复用(OCDM)信号是利用菲涅尔变换形成的一组正交线性啁啾(chirp)信号,基于OCDM 的雷达通信一体化信号不…

【重要】Heygen订阅指南和用法详解!让照片学说话?一张照片变演讲?Heygen订阅值得吗?

常见问题 Q&#xff1a;Heygen是什么&#xff1f;Heygen是什么玩意&#xff1f; A&#xff1a;Heygen是一款由AI视频工具,创作者只需要上传视频并选择要翻译的语言&#xff0c;该工具可实现自动翻译、调整音色、匹配嘴型。为了方便理解&#xff0c;笔者利用Heygen制作了一个AI视…

C语言中字符串函数以及内存函数的使用和注意事项

目录 0. 前言 1、求字符串长度函数 1.1、strlen 模拟实现 2.长度不受限制的字符串函数 2.1 strcpy 模拟实现 2.2strcat 模拟实现 2.3strcmp 模拟实现 3.长度受限制的字符串函数 3.1strncpy 3.2strncat 3.3strncmp 4、字符串查找函数 4.1strstr 模拟实现 3.2strt…

【C/C++笔试练习】线程作用、磁盘的固定块、多进程、进行调度、cache、内存抖动、非抢占CPU调度、inode描述、文件操作、进制、最难的问题、因子个数

文章目录 C/C笔试练习选择部分&#xff08;1&#xff09;线程作用&#xff08;2&#xff09;磁盘的固定块&#xff08;3&#xff09;多进程&#xff08;4&#xff09;进行调度&#xff08;5&#xff09;cache&#xff08;6&#xff09;内存抖动&#xff08;7&#xff09;非抢占…

一台服务器同时启动两个版本jdk

之前Java项目都是1.8的jdk&#xff0c;在服务器部署正常使用&#xff0c;服务器配置环境变量jdk1.8版本。最近一次我用了jdk17版本&#xff0c;部署服务器后&#xff0c;遇见了jdk版本不一致报错 报错内容&#xff1a; 52指向jdk1.8,61指向jdk17&#xff0c;大概就是jdk版本不…

第十六届“华中杯”B 题使用行车轨迹估计交通信号灯周期问题

某电子地图服务商希望获取城市路网中所有交通信号灯的红绿周期,以便为司机提供更好的导航服务。由于许多信号灯未接入网络,无法直接从交通管理部门获取所有信号灯的数据,也不可能在所有路口安排人工读取信号灯周期信息。所以,该公司计划使用大量客户的行车轨迹数据估计交通…

条件编译 #和##运算符

目录 1. #运算符2. ##运算符3. 条件编译4. 题目分享总结 正文开始 前言: 本章为C语言语法完结撒花, 下文将进行C语言中#和##操作符以及条件编译的讲解, 来进一步让我们了解C语言. 作者主页: 酷酷学!!! 1. #运算符 #运算符将宏的⼀个参数转换为字符串字⾯量。它仅允许出现在带…

牛客社区所有的表和SQL语句

文章目录 1 帖子表 discuss_post1.1 字段描述1.2 相关功能描述1.2.1 分页查询帖子1.2.2 查询帖子总数量1.2.3 插入一条帖子记录1.2.4 根据帖子ID查询某条帖子1.2.5 更新帖子评论数量1.2.6 更新帖子类型1.2.6 更新帖子状态1.2.7 更新帖子分数 2 用户表 user2.1 字段描述2.2 相关…

cesium primitive 移动 缩放 旋转 矩阵

旋转参考&#xff1a;cesium 指定点旋转rectangle Primitive方式 矩阵篇-CSDN博客 平移参考&#xff1a;cesium 调整3dtiles的位置 世界坐标下 相对坐标下 平移矩阵-CSDN博客 一、primitive方式添加polygon let polygonInstance new Cesium.GeometryInstance({geometry: Ce…

陆金所控股一季报到底是利好还是利空?

3月底&#xff0c;陆金所控股&#xff08;LU.N;06623.HK&#xff09;因其特别分红方案受到市场高度关注。但在4月23日发布的2024年一季度财报中&#xff0c;陆金所控股营收同比下降30.9%&#xff0c;净亏损8.3亿元。 两者对比&#xff0c;外界不由得对公司的经营状况产生疑惑。…

ROS 话题订阅模型之自定义消息类型 C++实现

ROS 话题订阅模型之自定义消息类型 1.自定义消息类型好处 ROS提供了许多标准的消息类型&#xff0c;如 std_msgs/String、sensor_msgs/Image 等&#xff0c;涵盖了很多常见的数据类型和传感器数据。但是&#xff0c;在实际的开发中&#xff0c;我们经常会遇到需要传输的数据类…

【Image captioning】论文阅读九—Self-Distillation for Few-Shot Image Captioning_2022

摘要 大规模图像字幕数据集的开发成本高昂,而大量未配对的图像和文本语料库可能有助于减少手动注释的工作。在本文中,我们研究了只需要少量带注释的图像标题对的少样本图像标题问题。我们提出了一种基于集成的自蒸馏方法,允许使用不成对的图像和字幕来训练图像字幕模型。该…

springcloud alibaba 整合seata的TCC

一、seata服务端搭建同上篇。 Seata的AT模式客户端两阶段提交流程源码分析 二、seata客户端的结构 1.示例DEMO工程 下单&#xff0c;扣余额&#xff0c; 减库存。 2. MAVEN配置。 父工程&#xff1a;由于spring-cloud-starter-alibaba-seata依赖的seata-spring-boot-starter…

C语言(static和extern)

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸各位能阅读我的文章&#xff0c;诚请评论指点&#xff0c;关注收藏&#xff0c;欢迎欢迎~~ &#x1f4a5;个人主页&#xff1a;小羊在奋斗 &#x1f4a5;所属专栏&#xff1a;C语言 本系列文章为个人学习笔记&#x…

Python写个二维码

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、进入官网下载二、下载一下三.输入代码 前言 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、进入官网下载 官网 pip insta…