<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## 11) 配置文件讀寫功能 ? 配置文件讀寫這里就不詳細介紹了,主要的配置文件格式如下 ```conf [reactor] ip = 127.0.0.1 port = 7777 maxConn = 1024 threadNum = 5 ``` ? 一個主題,下面很多key-value的鍵值對. 代碼如下。 ### 11.1 功能實現 > lars_reactor/include/config_file.h ```c #pragma once #include <string> #include <vector> #include <map> //定義一個存放配置信息的map //key 是string 存放一個標題section //value 是一個map 存放該標題下面的所有key-value鍵值對 typedef std::map<std::string, std::map<std::string, std::string> *> STR_MAP; typedef STR_MAP::iterator STR_MAP_ITER; //設計成單例模式 class config_file { public: ~config_file(); //獲取字符串類型配置信息 std::string GetString(const std::string& section, const std::string& key, const std::string& default_value = ""); //字符串集合配置信息 std::vector<std::string> GetStringList(const std::string& section, const std::string& key); //獲取整型類型配置信息 unsigned GetNumber(const std::string& section, const std::string& key, unsigned default_value = 0); //獲取布爾類型配置信息 bool GetBool(const std::string& section, const std::string& key, bool default_value = false); //獲取浮點類型配置信息 float GetFloat(const std::string& section, const std::string& key, const float& default_value); //設置配置文件所在路徑 static bool setPath(const std::string& path); //獲取單例 static config_file *instance(); private: config_file() { } //構造私有 //字符串配置文件解析基礎方法 bool isSection(std::string line, std::string& section); unsigned parseNumber(const std::string& s); std::string trimLeft(const std::string& s); std::string trimRight(const std::string& s); std::string trim(const std::string& s); bool Load(const std::string& path); static config_file *config;//唯一讀取配置文件實例 STR_MAP _map; }; ``` > lars_reactor/src/config_file.cpp ```c #include "config_file.h" #include <map> #include <fstream> #include <iostream> #include <sstream> #include <assert.h> #include <strings.h> config_file* config_file::config = NULL; config_file::~config_file() { for (STR_MAP_ITER it = _map.begin(); it != _map.end(); ++it) { delete it->second; } } //獲取字符串類型鍵值對 std::string config_file::GetString(const std::string& section, const std::string& key, const std::string& default_value) { STR_MAP_ITER it = _map.find(section); if (it != _map.end()) { std::map<std::string, std::string>::const_iterator it1 = it->second->find(key); if (it1 != it->second->end()) { return it1->second; } } return default_value; } //獲取浮點類型鍵值對 float config_file::GetFloat(const std::string& section, const std::string& key, const float& default_value) { std::ostringstream convert1; convert1 << default_value; //將浮點轉換成字符串,然后按照字符串業務處理 std::string default_value_str = convert1.str(); std::string text = GetString(section, key, default_value_str); std::istringstream convert2(text); float fresult; if (!(convert2 >> fresult)) //如果Result放不下text對應的數字,執行將返回0; fresult = 0; return fresult; } //價值配置文件 bool config_file::Load(const std::string& path) { std::ifstream ifs(path.c_str()); if (!ifs.good()) { return false; } std::string line; std::map<std::string, std::string> *m = NULL; while (!ifs.eof() && ifs.good()) { getline(ifs, line); std::string section; if (isSection(line, section)) { STR_MAP_ITER it = _map.find(section); if (it == _map.end()) { m = new std::map<std::string, std::string>(); _map.insert(STR_MAP::value_type(section, m)); } else { m = it->second; } continue; } size_t equ_pos = line.find('='); if (equ_pos == std::string::npos) { continue; } std::string key = line.substr(0, equ_pos); std::string value = line.substr(equ_pos + 1); key = trim(key); value = trim(value); if (key.empty()) { continue; } if (key[0] == '#' || key[0] == ';') // skip comment { continue; } std::map<std::string, std::string>::iterator it1 = m->find(key); if (it1 != m->end()) { it1->second = value; } else { m->insert(std::map<std::string, std::string>::value_type(key, value)); } } ifs.close(); return true; } std::vector<std::string> config_file::GetStringList(const std::string& section, const std::string& key) { std::vector<std::string> v; std::string str = GetString(section, key, ""); std::string sep = ", \t"; std::string substr; std::string::size_type start = 0; std::string::size_type index; while ((index = str.find_first_of(sep, start)) != std::string::npos) { substr = str.substr(start, index - start); v.push_back(substr); start = str.find_first_not_of(sep, index); if (start == std::string::npos) { return v; } } substr = str.substr(start); v.push_back(substr); return v; } //獲取整型類型鍵值對 unsigned config_file::GetNumber(const std::string& section, const std::string& key, unsigned default_value) { STR_MAP_ITER it = _map.find(section); if (it != _map.end()) { std::map<std::string, std::string>::const_iterator it1 = it->second->find(key); if (it1 != it->second->end()) { return parseNumber(it1->second); } } return default_value; } //獲取布爾類型鍵值對 bool config_file::GetBool(const std::string& section, const std::string& key, bool default_value) { STR_MAP_ITER it = _map.find(section); if (it != _map.end()) { std::map<std::string, std::string>::const_iterator it1 = it->second->find(key); if (it1 != it->second->end()) { if (strcasecmp(it1->second.c_str(), "true") == 0) { return true; } } } return default_value; } bool config_file::isSection(std::string line, std::string& section) { section = trim(line); if (section.empty() || section.length() <= 2) { return false; } if (section.at(0) != '[' || section.at(section.length() - 1) != ']') { return false; } section = section.substr(1, section.length() - 2); section = trim(section); return true; } unsigned config_file::parseNumber(const std::string& s) { std::istringstream iss(s); long long v = 0; iss >> v; return v; } std::string config_file::trimLeft(const std::string& s) { size_t first_not_empty = 0; std::string::const_iterator beg = s.begin(); while (beg != s.end()) { if (!isspace(*beg)) { break; } first_not_empty++; beg++; } return s.substr(first_not_empty); } std::string config_file::trimRight(const std::string& s) { size_t last_not_empty = s.length(); std::string::const_iterator end = s.end(); while (end != s.begin()) { end--; if (!isspace(*end)) { break; } last_not_empty--; } return s.substr(0, last_not_empty); } std::string config_file::trim(const std::string& s) { return trimLeft(trimRight(s)); } config_file *config_file::instance() { assert(config != NULL); return config; } //設置配置文件所在路徑 bool config_file::setPath(const std::string& path) { assert(config == NULL); //創建對象 config = new config_file(); //加載文件 return config->Load(path); } ``` ### 11.2 完成Lars Reactor V0.9開發 > serv.conf ```conf [reactor] ip = 127.0.0.1 port = 7777 maxConn = 1024 threadNum = 5 ``` > server.cpp ```c #include "tcp_server.h" #include <string> #include <string.h> #include "config_file.h" //回顯業務的回調函數 void callback_busi(const char *data, uint32_t len, int msgid, net_connection *conn, void *user_data) { printf("callback_busi ...\n"); //直接回顯 conn->send_message(data, len, msgid); } //打印信息回調函數 void print_busi(const char *data, uint32_t len, int msgid, net_connection *conn, void *user_data) { printf("recv client: [%s]\n", data); printf("msgid: [%d]\n", msgid); printf("len: [%d]\n", len); } //新客戶端創建的回調 void on_client_build(net_connection *conn, void *args) { int msgid = 101; const char *msg = "welcome! you online.."; conn->send_message(msg, strlen(msg), msgid); } //客戶端銷毀的回調 void on_client_lost(net_connection *conn, void *args) { printf("connection is lost !\n"); } int main() { event_loop loop; //加載配置文件 config_file::setPath("./serv.conf"); std::string ip = config_file::instance()->GetString("reactor", "ip", "0.0.0.0"); short port = config_file::instance()->GetNumber("reactor", "port", 8888); printf("ip = %s, port = %d\n", ip.c_str(), port); tcp_server server(&loop, ip.c_str(), port); //注冊消息業務路由 server.add_msg_router(1, callback_busi); server.add_msg_router(2, print_busi); //注冊鏈接hook回調 server.set_conn_start(on_client_build); server.set_conn_close(on_client_lost); loop.event_process(); return 0; } ``` --- ### 關于作者: 作者:`Aceld(劉丹冰)` mail: [danbing.at@gmail.com](mailto:danbing.at@gmail.com) github: [https://github.com/aceld](https://github.com/aceld) 原創書籍: [http://www.hmoore.net/@aceld](http://www.hmoore.net/@aceld) ![](https://img.kancloud.cn/b0/d1/b0d11a21ba62e96aef1c11d5bfff2cf8_227x227.jpg) >**原創聲明:未經作者允許請勿轉載, 如果轉載請注明出處**
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看