如何用Boost解析ini文件 [c++]


Answers

由於其簡單的結構,解析INI文件是容易的。 使用AX我可以寫幾行來解析部分,屬性和註釋:

auto trailing_spaces = *space & endl;
auto section = '[' & r_alnumstr() & ']';
auto name = +(r_any() - '=' - endl - space);
auto value = '"' & *("\\\"" | r_any() - '"') & '"'
   | *(r_any() - trailing_spaces);
auto property = *space & name & *space & '=' & *space 
    & value & trailing_spaces;
auto comment = ';' & *(r_any() - endl) & endl;
auto ini_file = *comment & *(section & *(prop_line | comment)) & r_end();

更詳細的例子可以在Reference.pdf中找到

關於不讀整個文件,可以用不同的方法來完成。 首先,INI格式的解析器至少需要前向迭代器,所以你不能使用流迭代器,因為它們是輸入迭代器。 您可以創建一個單獨的類與所需的迭代器流(我寫了一個這樣的類過去與滑動緩衝區)。 您可以使用內存映射文件。 或者您可以使用動態緩衝區,從標準流讀取並提供給解析器,直到找到值。 如果你不想擁有一個真正的解析器,並且不關心INI文件結構是否正確,那麼你可以簡單地在文件中搜索你的記號。 輸入迭代器就足夠了。

最後,我不確定避免閱讀整個文件帶來的好處。 INI文件通常很小,而且由於硬盤驅動器和多個緩衝系統無論如何都會讀取一個或多個扇區(即使只需要一個字節),所以我懷疑部分讀取文件會有任何性能改善反复做),可能是相反的。

Question

我有一個ini文件,其中包含一些示例值,如:

[Section1]
Value1 = 10
Value2 = a_text_string

我試圖加載這些值,並用Boost在我的應用程序中打印它們,但我不明白如何在C ++中執行此操作。

我在這個論壇搜索,以找到一些例子(我總是使用C,所以我不是很好的C + +),但我只發現如何從文件一次讀取值的例子。

我需要加載一個單一的值,如string = Section1.Value2因為我不需要讀取所有的值,但只是其中的一小部分。

我想加載單個值並將其存儲在變量中,以便在我的應用程序中使用它們。

Boost可以做到這一點嗎?

目前,我正在使用這個代碼:

#include <iostream>
#include <string>
#include <set>
#include <sstream>
#include <exception>
#include <fstream>
#include <boost/config.hpp>
#include <boost/program_options/detail/config_file.hpp>
#include <boost/program_options/parsers.hpp>

namespace pod = boost::program_options::detail;

int main()
{
   std::ifstream s("file.ini");
    if(!s)
    {
        std::cerr<<"error"<<std::endl;
        return 1;
    }

    std::set<std::string> options;
    options.insert("Test.a");
    options.insert("Test.b");
    options.insert("Test.c");

    for (boost::program_options::detail::config_file_iterator i(s, options), e ; i != e; ++i)
        std::cout << i->value[0] << std::endl;
   }

但是這只是讀取for循環中的所有值; 相反,我只想讀取單個值,當我需要時,我不需要在文件中插入值,因為它已經寫在我的程序中需要的所有值。




該文件需要被解析,這必須按順序進行。 因此,我只是讀取整個文件,將所有值存儲在某個集合( mapunordered_map ,可能使用pair<section, key>作為鍵或使用地圖映射),並在需要時從中獲取它們。