颛孙中 发表于 2025-6-22 23:29:13

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

开发环境及功能

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


[*]文件目录结构,未编译的目录
.
├── CMakeLists.txt
├── config.ini
├── include
│   └── ConfigReader.h
├── main.cpp
└── src
    └── ConfigReader.cpp代码实现


[*]ConfigReader.h实现
#pragma once
#include <string>
#include <stdexcept>
#include <map>
#include <unordered_map>

class ConfigReader{
public:
      //explicit 禁用隐式调用,使用时,必须显示的调用
      explicit ConfigReader(const std::string& fileName);
      // const std::string &key 表示不会对key进行修改,不会修改传入的参数值 &避免拷贝
      // const 表示是一个常量成员函数,不会修改类的任何成员变量
      std::string getString(const std::string &key) const;
      int getInt(const std::string &key) const;
      double getDouble(const std::string &key) const;
      bool getBool(const std::string &key) const;
private:
      //存放解析结果、
      //map 使用红黑树实现,键唯一,插入的键值对会按键的升序排序,查找、插入、删除速度为O(logn)
      //unordered_map使用hash表实现,键唯一,无序,平局查找、插入、删除时间复杂度为O(1),最坏o(n),占内存更多(维护hash表)
      //multimap使用红黑树实现,可以键重复,按键升序排列,查找、插入、删除速度为O(logn)
      std::unordered_map<std::string,std::string> configMap;

      //去除字符串空白字符
      static std::string trim(const std::string & str);

      //解析配置文件
      void parseFile(const std::string &fileName);


};

[*]ConfigReader.cpp
#include "ConfigReader.h"
#include <fstream>

ConfigReader::ConfigReader(const std::string &fileName){

      parseFile(fileName);
}

//把所有非注释的行添加到map结构中
void ConfigReader::parseFile(const std::string &fileName){

      std::ifstream file(fileName);
      if(!file.is_open()){
                throw std::runtime_error("Failed to open config file:"+fileName);
      }
      std::string line;
      while(std::getline(file,line)){
                //获取第一个#或/的位置
                size_t commentPos = line.find_first_of("#/");
                //如果该行有#或者/,则认为改行为注释行
                if(std::string::npos != commentPos){
                        continue;
                }
                size_t equalPos = line.find('=') != std::string::npos ? line.find('=') : line.find(':');
                if(std::string::npos == equalPos){
                        continue;
                }
                std::string key = trim(line.substr(0,equalPos));
                std::string value = trim(line.substr(equalPos+1));

                if(!key.empty()){
                        configMap = value;
                }

      }

}

//处理字符串首尾的空格
std::string ConfigReader::trim(const std::string& str){
      if(str.empty()) return str;
      auto start = str.begin();
      while(start != str.end() && std::isspace(*start)){
                start++;
      }
      auto end = str.end();
      do{
                end--;
      }while(std::distance(start,end)>0 && std::isspace(*end));
      return std::string(start,end+1);
}


std::string ConfigReader::getString(const std::string & key) const{
      auto it = configMap.find(key);
      if(it == configMap.end()){
                throw std::out_of_range("config key not found:"+key);
      }
      return it->second;
}


intConfigReader::getInt(const std::string & key) const{
      std::string value = getString(key);
      try{
                return std::stoi(value);
      }
      catch(const std::exception & e){
                throw std::runtime_error("Invalid integer value for key"+key+":"+value);
      }
}

      }
      return it->second;
}

double ConfigReader::getDouble(const std::string & key) const{
      std::string value = getString(key);
      try{
                return std::stod(value);
      }
      catch(const std::exception & e){
                throw std::runtime_error("Invalid double value for key"+key+":"+value);
      }
}

bool ConfigReader::getBool(const std::string & key) const{
      std::string value = getString(key);
      try{
                if(value == "true")
                        return true;
                else if(value == "false")
                        return false;
      }
      catch(const std::exception & e){
                throw std::runtime_error("Invalid integer value for key"+key+":"+value);
      }
}

[*]main.cpp
#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
页: [1]
查看完整版本: 【C++】读取配置文件工具类