用C ++解析配置文件中的“部分”

时间:2018-01-22 00:25:20

标签: c++ parsing configuration

我想知道是否有一种优雅的方法来解析C ++中的典型配置文件。

# This is a comment

log =/var/log/secure

max_tries=5

max_reports=2

以下是我目前的情况:

std::string buf;
smatch matches;
int line_number = 0; // keeping track of the line number allows for error identification
std::unordered_map<std::string, std::string> parsed_options;

while (std::getline(is, buf)) {
    // is the line a comment or blank?
    if ((buf.find_first_of('#') == 0) || (std::all_of(buf.begin(), buf.end(), isspace)) || (buf.empty())) {
    } else {
        std::istringstream configs(buf);
        std::string option;
        if (std::getline(configs, option, '=')) {
            std::string val;
            if (std::getline(configs, val)) {
                option.erase(std::remove_if(option.begin(), option.end(), isspace), option.end());
                val.erase(std::remove_if(val.begin(), val.end(), isspace), val.end());
                parsed_options.emplace(std::make_pair(option, val));
            }

        } else {
            std::stringstream se;
            se << "Coud not parse option at line " << line_number;
            throw std::runtime_error(se.str());
        }
    }
    ++line_number;
}

for (auto i : parsed_options) {
    if (i.first == "log") {
        auth_log_ = i.second;
    } else if (i.first == "max_tries") {
        max_attempts_ = std::stoi(i.second);
    } else if (i.first == "max_reports") {
        max_reports_ = std::stoi(i.second);
    } else if (i.first == "interval") {
        interval_ == std::stoi(i.second);
    } else {
        std::cout << "\"" << i.first << "\" " << i.second << '\n';
        std::stringstream ss1;
        ss1 << "Invalid option at line " << line_number;
        throw std::runtime_error(ss1.str());
    }
}

}

虽然这有效,但我有一个问题。我想添加对所谓“部分”的支持。

# This is a comment

[section1]
log =/var/log/secure

max_tries=5

max_reports=2

[section2]
log =/var/log/secure

max_tries=5

max_reports=2

鉴于此配置文件,我理想情况下可以分别解析这些部分。最终我将需要它,我可以阅读部分名称,并使用每个部分下的选项没有冲突。如果每个部分下的名称与另一个部分的名称相匹配,我需要能够从两个部分中提取值而不会遇到问题。我宁愿不使用Boost看到我更喜欢STL,但如果证明它更快更有效,我将使用它。

1 个答案:

答案 0 :(得分:0)

您的配置文件似乎是一个ini?

周围有一堆ini解析器,如果这是一个选项,它将为您节省从头编写自己的工作: