본문 바로가기

Library/C/C++

boost::program_options: getopt()을 사용할 수 없을 때

C/C++을 사용하여 콘솔 프로그램을 작성할 때, 프로그램의 옵션를 처리해야 할 필요가 있다. 간단한 옵션 한 두개가 아니라, 제대로 된 옵션 처리를 구현하는 것은 간단한 일이 아니다. UNIX 계열 프로그램들은 하이픈(-) 기호를 사용하여 각 토큰이 프로그램에서 필요로 하는 옵션이라는 것을 나타내며, 보통 한 글자를 사용한다. GNU는 더블 하이픈을 사용하여 한 글자 이상의 문자열을 사용하여 옵션를 나타낸다.

 

문제는, 옵션를 제대로 처리하는 것은 간단한 일이 아니라는 것이다. 제일 먼저, 실행 시점에서 주어지는 인자들의 집합을 토큰으로 분리해야 하며, 각 토큰들은 순서 의존적인 추가 설정값을 가질 수도 있다. 또, 특정 토큰들은 위치에 상관없이 나타날 수도 있다. 이 요구 사항들은 짧은 시간 안에 완벽하게 구현하기 힘들다.

 

당연히, 이런 요구에 부응하여 잘 만들어진 구현이 존재하는데, UNIX 플랫폼에서는 getopt() 함수를 사용할 수 있다. getopt() 함수는 C/C++의 int main(int argc, char *argv[])의 argv를 토큰화하고, 다른 토큰이 특정 토큰과 관련된 설정값인지 따위를 해석할 수 있는 방법을 제공한다. getopt() 함수는 상당히 직관적으로 구현되어 있어서 이해하기 쉽고, 사용하기 편리하다. 그러나, getopt() 함수는 unistd.h에 포함되어 있기 때문에, 다른 플랫폼에서 사용하기 어렵다는 문제가 있다. 단순히 getopt()만 사용하는 것이 목적이라면 CygWin을 사용할 수 있지만, 예를 들어, 콘솔 기반에서 윈도우 헤더 파일과 라이브러리를 사용하는 프로그램을 작성해야 한다면 CygWin을 사용 할 수 없다.

 

이럴 경우, 가장 좋은 대안은 boost::program_options이다. boost::program_options은 실행 시점에서 argc와 argv를 해석하여 토큰화할 뿐만 아니라, 간단한 코딩만으로 싱글 하이픈 스타일과 더블 하이픈 스타일의 옵션들을 다룰 수 있도록 해준다. 특히, 순서에 상관없이 처리해야 하는 특정 옵션들을 처리할 수 있는 방법도 제공하며, 여기에 그치지 않고 ini 스타일의 설정 파일을 직접 해석하여 옵션으로 등록하는 기능까지 제공한다. boost::program_options은 getopt()의 단순한 대타가 아니다. C++ 코드를 작성하고 있다면, getopt()보다 우선적으로 사용을 고려해볼 정도로, 매우 잘 만들어진 옵션 처리기다.

 

boost.org에 워낙 설명이 잘 되어 있기 때문에, 해당 문서를 읽어보는 것으로도 충분히 원하는 코드를 작성할 수 있을 것이다. 그러나, 한 가지 문서에 설명이 되어 있지 않은 부분이 있는데, 그것은 parse_config_file 클래스를 사용하여 해당 값을 읽어들일 때, 실제 설정값을 문자열로 읽어야 한다는 것이다. 또, 유니코드를 사용했을 때 parse_command_line 함수나 command_line_parser가 wchat_t 타입의 argv와 문제를 일으킬 수도 있는데, 가급적 표준 C/C++ 진입 함수, 즉 int main(int argc, char *argv[]) 함수를 사용하길 권한다. int wmain(int argc, wchat_t *argv[])은 마이크로소프트의 독자 확장이며, 표준 C/C++와 상관없다.

 

 


Reference

http://www.boost.org/doc/libs/1_54_0/doc/html/program_options.html