C++/Boost

[Boost] program_options

로파이 2022. 8. 20. 16:46

boost의 program_options을 사용해본다.

 

프로그램 시작 인수를 ./program.exe --option=value 과 같이 실행하고 필요 정보를 출력할 수 있게 해준다.

 

필요 헤더

#include <boost/program_options.hpp>

 

사용 방법

1. options_description 개체를 정의를 해준다.

2. 프로그램 인수를 파싱한다.

3. 프로그램 인수를 적용한다.

 

특징

  • options_description의 add_option()을 할 때 인수를 필수로 지정하거나 기본값을 지정하는 등을 할 수 있다.
  • ./program.exe --help를 통해 옵션 정보를 출력할 수 있다.
  • .cfg 파일을 통해 인수를 설정할 수 있다.
#include "global.h"

#ifdef _DEBUG
#pragma comment(lib, "libboost_program_options-vc143-mt-gd-x64-1_80.lib")
#else
#pragma comment(lib, "libboost_program_options-vc143-mt-x64-1_80.lib")
#endif
#include <boost/program_options.hpp>
namespace opt = boost::program_options;
using std::cout;
using std::endl;

class ProgramOptions
{
public:
	static int check(int argc, char** argv)
	{
		// 1. 옵션 정보를 담는 개체를 정의한다.
		opt::options_description desc("all options");

		// 2. 필요 옵션을 정의한다.
		// - 첫번째 인수는 커맨드 라인상 이름이다.
		// - 두번째 인수는 값 타입을 정의한다.
		// - 세번째 인수는 옵션의 설명이다.
		desc.add_options()
			("hostname,host", opt::value<std::string>()->required(), "connecting host name")
			("port,p", opt::value<unsigned short>()->required(), "connecting port")
			("name", opt::value<std::string>()->default_value("root"), "connecting username")
			("help", "help message")
			;

		// 3. 프로그램 인수로 부터 옵션 변수를 저장하기 위한 개체를 정의하고 인수로부터 파싱한다.
		opt::variables_map vm;
		try
		{
			opt::store(opt::parse_command_line(argc, argv, desc), vm);
		}
		catch (const std::exception& e)
		{
			cout << "Parse Error: " << e.what() << endl;
			return -1;
		}
		
		// 4. help를 인수로 사용한 경우
		if (vm.count("help")) {
			cout << desc << "\n";
			return 1;
		}

		// 5. cfg 파일로 부터 설정되지 않은 옵션을 설정할 수 있다.
		// XXX.cfg 파일의 구성은 다음과 같이 되어 있어야한다.
		// variable=value
		try
		{
			opt::store(opt::parse_config_file<char>("myconfig.cfg", desc), vm);
		}
		catch (const opt::reading_file& e)
		{
			cout << "Error: " << e.what() << endl;
		}

		// 6. 인수를 적용한다.
		try
		{
			opt::notify(vm);
		}
		catch (const opt::required_option& e) {
			cout << "Error: " << e.what() << endl;
			return 2;
		}

		std::cout << "host:" << vm["hostname"].as<std::string>() << vm["port"].as<unsigned short>() << endl;

		if (vm.count("name"))
		{
			std::cout << "name: " << vm["name"].as<std::string>() << endl;
		}
		
		return 0;
	}
};

사용 예시