Boost::program_options 사용기
오늘은 아침부터 일이 잘 되지 않는다
머리가 잘 안 돌아가서 막막한 느낌 ㅠ.,ㅜ
그래서~~ 기분 전환 용으로 글 하나 쌈박하게 올리고 다시 열일 해보겠다
이전에 작성한 boost 관련 글에도 썼다시피
나는 boost에 많은 고마움을 느낀다 +_+ 엥 이게 있다고? 하는 라이브러리가 많기 때문
이번에 시뮬레이터를 작성할 게 있어서 C로 하려다가 C++로 하려는데
세상에.. Boost에는 program options라는 기능을 제공해서
argument 기능을 참 쉽게 만들 수 있게 해 놓았다
1. 긴 서론
우리가 어떤 프로그램을 실행할 때, 옵션을 추가하여 실행을 해본 경험이 있을 것이다
argument를 프로세스 실행 파일 뒤에 추가해서 사용하곤 하는데
$ gcc --help
Usage: gcc [options] file...
Options:
-pass-exit-codes Exit with highest error code from a phase
--help Display this information
--target-help Display target specific command line options
--help={common|optimizers|params|target|warnings|[^]{joined|separate|undocumented}}[,...]
...
프로그램뿐만 아니라 command에 대한 정보를 얻을 때도 사용하는 방법이다
Usage를 확인하고 싶을 때 --h 또는 --help 요런 식으로
사용할 수 있는 옵션의 목록을 확인할 수도 있다
이 기능을 구현할 수 있도록 라이브러리를 제공을 해주는 우리의 Boost..
https://www.boost.org/doc/libs/1_79_0/doc/html/program_options/tutorial.html
Tutorial - 1.79.0
In this section, we'll take a look at the most common usage scenarios of the program_options library, starting with the simplest one. The examples show only the interesting code parts, but the complete programs can be found in the "BOOST_ROOT/libs/program_
www.boost.org
시간이 조금 있을 때 한번 읽어보는 것을 추천한다
만약 이걸 사용하기 싫고 내가 구현하고 싶다?? 또는 C로 개발하고 싶다??
그렇다면 정말 많은 단계의 if-else 문을 쓰며 허우적거릴 것이다...
나도 그랬다
2. 사용법
우선 Header file 및 라이브러리는 아래와 같이 사용해야 한다
#include <boost/program_options.hpp>
using namespace boost::program_options;
boost_program_options
바로 예제부터 보고~~ 하나하나 정리해보겠다
(1) options_description
string name;
int age = 0;
options_description desc{"Options"};
desc.add_options()
("help,h", "Help screen")
("name", value<string>(&name)->default_value("bell2"), "User Name")
("age", value<int>(&age)->notifier(on_age), "User Age");
options_description class를 사용하면 usage의 설명을 붙일 수 있다
또한 add_options()라는 함수에 operator()를 사용하여 편하게 항목을 추가할 수 있다
("name", value<string>()->default_value("bell2"), "User Name")
요렇게 쓰면 "name"은 추가할 options의 key가 되고, 두 번째 인자에는 value가 추가된다
이렇게 key, value 형태로 저장을 하면 저 key로 값을 가져오는 등의 연산이 가능하다
두 번째 인자의
value<string>(&name)->default_value("bell2")
요것은 --name의 옵션의 값은 string으로 가져올 것이고,
그 가져온 값을 name이라는 변수에 저장한다는 뜻이다
default_value를 설정할 수도 있고, value<string>(&name)만 사용할 수도 있다
그리고 세 번째 인자는 해당 옵션의 설명으로, --help 옵션을 입력 시에 커맨드 창에 보여준다
두 번째 인자들을 잘 보면 default_value 말고도 notifier라는 것이 있는데
value<int>(&age)->notifier(on_age)
얘는 on_age라는 callback 함수를 등록해서, age 옵션 값이 있으면 on_age()라는 함수가 call이 된다
(2) variables_map
얘가 참 재밌는 기능이라고 생각했다
variables_map vm;
store(parse_command_line(argc, argv, desc), vm);
notify(vm);
vaialbe_map이라는 건 옵션들을 key, value 형태로 map으로 저장을 해준다
store()
옵션들에 대해 최종 값으로 저장을 해준다
우선순위나 notify 여부 등을 포함해서~~
notify()
예는 옵션의 최종 값이 결정되면 해당 옵션에서 수행해야 하는 기능을 자동으로 수행해서
캡슐화할 수 있도록 해준다
아까 on_age 같은 callback 함수를 등록하면 이를 실행해준다는 뜻
(3) 결과 출력하기
if (vm.count("help"))
std::cout << desc << '\n';
else if (vm.count("age"))
std::cout << "Age: " << vm["age"].as<int>() << '\n';
else if (vm.count("name"))
std::cout << "Name: " << vm["name"].as<string>() << '\n';
...
그럼 결과를 어떻게 출력하느냐
값 저장은 위해서 설명한 것처럼 value<T>(&name) 이렇게 해야 하고
만약 저장은 안 하고 가볍게 출력만 하고 싶다면
vm["age"].as<int>() 이렇게 해주면 된다
전체 코드는 다음과 같다
#include <boost/program_options.hpp>
#include <iostream>
#include <string>
using namespace boost::program_options;
using namespace std;
void on_age(int age)
{
std::cout << "On age: " << age << '\n';
}
int main(int argc, const char *argv[])
{
try
{
options_description desc{"Options"};
desc.add_options()
("help,h", "Help screen")
("name", value<string>()->default_value("bell2"), "User Name")
("age", value<int>()->notifier(on_age), "User Age");
variables_map vm;
store(parse_command_line(argc, argv, desc), vm);
notify(vm);
if (vm.count("help"))
std::cout << desc << '\n';
else if (vm.count("age"))
std::cout << "Age: " << vm["age"].as<int>() << '\n';
else if (vm.count("name"))
std::cout << "Name: " << vm["name"].as<string>() << '\n';
}
catch (const error &ex)
{
std::cerr << ex.what() << '\n';
}
return 0;
}
그럼 이만
참고 자료
https://www.boost.org/doc/libs/1_79_0/doc/html/program_options/overview.html#id-1.3.32.5.7.9
Library Overview - 1.79.0
In the tutorial section, we saw several examples of library usage. Here we will describe the overall library design including the primary components and their function. To be a little more concrete, the options_description class is from the options descrip
www.boost.org