Evgenii Legotckoi
18 листопада 2018 р. 16:57

Boost - консольне меню програми за допомогою boost::program_options

А ось і стаття по boost з моїх деяких матеріалів, що накопичилися. Пропоную до вашої уваги варіант написання консольної програми з підтримкою консольного меню, яке реалізується за допомогою boost::program_options .

boost::program_options відповідає за обробку аргументів, що передаються програмі, і встановлює всі необхідні змінні без необхідності реалізовувати довгу логіку з if else гілок. Це вже реалізується всередині boost::program_optons .

Припустимо, що наша програма прийматиме як аргументи такі дані

  • шлях до вхідного файлу
  • шлях до вихідного файлу
  • Розмір оброблюваного блоку, неважливо для чого, ми не будемо з ним нічого робити, просто є такий параметр у програмі.

Також програма буде мати меню help, яке і буде даним консольним меню.

На малюнку нижче представлений варіант використання цієї програми.


Структура проекту

Ця програма буде написана з використанням системи складання CMake без використання Qt бібліотеки . Це буде туторіал чисто для boost.

Подивимося на структуру проекту.

У цьому проекті є

  • CMakeLists.txt - конфігураційний файл CMake
  • main.cpp - файл з main функцією
  • EApplication.h - заголовний файл основного класу програми
  • EApplication.cpp - файл вихідних кодів основного класу програми

Напишемо проект із використанням ОВП.

CMakeLists.txt

Для початку розберемося зі зміною проекту, оскільки цей проект написаний з використанням бібліотеки boost, то його потрібно налаштувати, щоб він запрацював.

Зазначу, що цей проект створювався під операційною системою Linux, тому можуть бути відмінності у налаштуваннях під операційною системою Windows або Mac OS.

Також, якщо у вас не встановлений комплект розробки Boost, то, наприклад, під Ubuntu ви це можете зробити так

sudo apt-get install libboost-all-dev

Подивимося на налаштування проекту

cmake_minimum_required(VERSION 3.12)
project(Menu)

set(CMAKE_CXX_STANDARD 17)

find_package(Boost 1.58.0 COMPONENTS filesystem program_options)

set(SOURCE_FILES
        main.cpp
        EApplication.cpp
        EApplication.h)

if(Boost_FOUND)
    include_directories(${Boost_INCLUDE_DIRS})
    add_executable(Menu ${SOURCE_FILES})
    target_link_libraries(Menu ${Boost_LIBRARIES})
endif()

Як бачите, я підключив стандарт C++17. В даному випадку це не важливо, можна зібрати проект і на стандартах C + + 11 або C + + 14.

Тут вказано мінімально потрібну версію CMake. Ця версія була встановлена у мене на PC.

Потім шукаємо потрібні нам компоненти boost.

  • filesystem - будемо зберігати інформацію про файл
  • program_options - для формування консольного меню

В умові if enfif вказані бібліотеки, їх заголовні файли та вихідні файли проекту.

main.cpp

Подивимося на вміст файлу з main функцією. Там буде створюватись екземпляр програми та виконуватиметься його метод exec() для запуску основної програмної логіки.

#include <iostream>

#include "EApplication.h"

int main(int argc, const char* argv[])
{
    EApplication app(argc, argv);
    return app.exec();
}

EApplication.h

А тепер найцікавіше сама програма з консольним меню.

#ifndef MENU_EAPPLICATION_H
#define MENU_EAPPLICATION_H

#include <boost/program_options.hpp>
#include <boost/filesystem/fstream.hpp>

namespace po = boost::program_options;
namespace fs = boost::filesystem;

class EApplication
{
public:
    explicit EApplication(int argc, const char** argv);

    int exec();

private:
    // Описание доступных опций меню
    po::options_description m_desc {"Allowed options"};
    po::variables_map m_vm; // контейнер для сохранения выбранных опций программы

    // Требуемые в программе переменные для работы с опциями меню
    size_t m_blockSize;
    fs::path m_inputFilePath;
    fs::path m_outputFilePath;
};


#endif //MENU_EAPPLICATION_H

EApplication.cpp

#include "EApplication.h"

#include <iostream>

EApplication::EApplication(int argc, const char **argv)
{
    // Добавляем пункты меню
    m_desc.add_options()
            ("help", "produce help message")  // Вызов help справки
            ("input-file,i",  po::value<fs::path>(&m_inputFilePath)->composing(), "set input file path")              // Входной файл, можно записать либо --input-file, либо -i
            ("output-file,o", po::value<fs::path>(&m_outputFilePath)->composing(), "set output file path")            // Выходной файл
            ("block-size,b",  po::value<size_t>(&m_blockSize)->default_value(1024 * 1024), "set block size in bytes") // Размер блока
            ;
    po::store(po::parse_command_line(argc, argv, m_desc), m_vm);  // парсим переданные аргументы
    po::notify(m_vm); // записываем аргументы в переменные в программе
}

int EApplication::exec()
{
    // Если есть запрос на справку
    if (m_vm.count("help"))
    {
        // То выводим описание меню
        std::cout << m_desc << std::endl;
        return 1;
    }

    // Если были введены как минимум входной и выходной параметры
    if (m_vm.count("input-file") && m_vm.count("output-file"))
    {
        // то делаем инициализацию программы, но в данном случае только выводим информацию о введённых параметрах
        std::cout << m_inputFilePath << '\t' << m_outputFilePath << '\t' << m_blockSize << std::endl;
    }
    else
    {
        // В противном случае предлагаем посмотреть справку
        std::cout << "Please, use --help option for information" << std::endl;
        return 1;
    }

    // ToDo something
    // Здесь можем поместить в цикле while() или for(;;) логику программы

    return 0;
}

Висновки

Ця бібліотека boost::program_options справді дуже корисна і дозволяє позбавитися великої кількості проблем при написанні консольного меню. Як мінімум, вона дозволяє написати дуже компактний програмний код, а також дуже швидко впровадити меню в консольну програму.

Посилання на сховище Git

Вам це подобається? Поділіться в соціальних мережах!

Коментарі

Only authorized users can post comments.
Please, Log in or Sign up