找回密码
 立即注册
首页 业界区 业界 【C++】读取配置文件工具类

【C++】读取配置文件工具类

颛孙中 2025-6-22 23:29:13
开发环境及功能

开发环境:linux
开发语言:C++
编译工具:g++、cmake
调试:gdb
目的:使用C++实现一个读取配置文件的工具类,目的是读取key=value形式的配置,提高代码灵活性,解耦合。
实现


  • 文件目录结构,未编译的目录
  1. .
  2. ├── CMakeLists.txt
  3. ├── config.ini
  4. ├── include
  5. │   └── ConfigReader.h
  6. ├── main.cpp
  7. └── src
  8.     └── ConfigReader.cpp
复制代码
代码实现


  • ConfigReader.h实现
  1. #pragma once
  2. #include <string>
  3. #include <stdexcept>
  4. #include <map>
  5. #include <unordered_map>
  6. class ConfigReader{
  7. public:
  8.         //explicit 禁用隐式调用,使用时,必须显示的调用
  9.         explicit ConfigReader(const std::string& fileName);
  10.         // const std::string &key 表示不会对key进行修改,不会修改传入的参数值 &避免拷贝
  11.         // const 表示是一个常量成员函数,不会修改类的任何成员变量
  12.         std::string getString(const std::string &key) const;
  13.         int getInt(const std::string &key) const;
  14.         double getDouble(const std::string &key) const;
  15.         bool getBool(const std::string &key) const;
  16. private:
  17.         //存放解析结果、
  18.         //map 使用红黑树实现,键唯一,插入的键值对会按键的升序排序,查找、插入、删除速度为O(logn)
  19.         //unordered_map使用hash表实现,键唯一,无序,平局查找、插入、删除时间复杂度为O(1),最坏o(n),占内存更多(维护hash表)
  20.         //multimap使用红黑树实现,可以键重复,按键升序排列,查找、插入、删除速度为O(logn)
  21.         std::unordered_map<std::string,std::string> configMap;
  22.         //去除字符串空白字符
  23.         static std::string trim(const std::string & str);
  24.         //解析配置文件
  25.         void parseFile(const std::string &fileName);
  26. };
复制代码

  • ConfigReader.cpp
  1. #include "ConfigReader.h"
  2. #include <fstream>
  3. ConfigReader::ConfigReader(const std::string &fileName){
  4.         parseFile(fileName);
  5. }
  6. //把所有非注释的行添加到map结构中
  7. void ConfigReader::parseFile(const std::string &fileName){
  8.         std::ifstream file(fileName);
  9.         if(!file.is_open()){
  10.                 throw std::runtime_error("Failed to open config file:"+fileName);
  11.         }
  12.         std::string line;
  13.         while(std::getline(file,line)){
  14.                 //获取第一个#或/的位置
  15.                 size_t commentPos = line.find_first_of("#/");
  16.                 //如果该行有#或者/,则认为改行为注释行
  17.                 if(std::string::npos != commentPos){
  18.                         continue;
  19.                 }
  20.                 size_t equalPos = line.find('=') != std::string::npos ? line.find('=') : line.find(':');
  21.                 if(std::string::npos == equalPos){
  22.                         continue;
  23.                 }
  24.                 std::string key = trim(line.substr(0,equalPos));
  25.                 std::string value = trim(line.substr(equalPos+1));
  26.                 if(!key.empty()){
  27.                         configMap[key] = value;
  28.                 }
  29.         }
  30. }
  31. //处理字符串首尾的空格
  32. std::string ConfigReader::trim(const std::string& str){
  33.         if(str.empty()) return str;
  34.         auto start = str.begin();
  35.         while(start != str.end() && std::isspace(*start)){
  36.                 start++;
  37.         }
  38.         auto end = str.end();
  39.         do{
  40.                 end--;
  41.         }while(std::distance(start,end)>0 && std::isspace(*end));
  42.         return std::string(start,end+1);
  43. }
  44. std::string ConfigReader::getString(const std::string & key) const{
  45.         auto it = configMap.find(key);
  46.         if(it == configMap.end()){
  47.                 throw std::out_of_range("config key not found:"+key);
  48.         }
  49.         return it->second;
  50. }
  51. int  ConfigReader::getInt(const std::string & key) const{
  52.         std::string value = getString(key);
  53.         try{
  54.                 return std::stoi(value);
  55.         }
  56.         catch(const std::exception & e){
  57.                 throw std::runtime_error("Invalid integer value for key"+key+":"+value);
  58.         }
  59. }
  60.         }
  61.         return it->second;
  62. }
  63. double ConfigReader::getDouble(const std::string & key) const{
  64.         std::string value = getString(key);
  65.         try{
  66.                 return std::stod(value);
  67.         }
  68.         catch(const std::exception & e){
  69.                 throw std::runtime_error("Invalid double value for key"+key+":"+value);
  70.         }
  71. }
  72. bool ConfigReader::getBool(const std::string & key) const{
  73.         std::string value = getString(key);
  74.         try{
  75.                 if(value == "true")
  76.                         return true;
  77.                 else if(value == "false")
  78.                         return false;
  79.         }
  80.         catch(const std::exception & e){
  81.                 throw std::runtime_error("Invalid integer value for key"+key+":"+value);
  82.         }
  83. }
复制代码

  • main.cpp
[code]#include #include "ConfigReader.h"int main() {    try {        ConfigReader config("config.ini");        std::string ip = config.getString("server_ip");        int port = config.getInt("server_port");        double timeout = config.getDouble("timeout");        bool debug = config.getBool("debug_mode");        std::string log_path = config.getString("log_path");        std::cout
您需要登录后才可以回帖 登录 | 立即注册