option=value
구문 사용argparse.hpp를 포함하기만 하면 됩니다.
# include < argparse/argparse.hpp >
명령줄 인수 구문 분석을 시작하려면 ArgumentParser
를 만듭니다.
argparse::ArgumentParser program ( " program_name " );
참고: 프로그램 버전인 ArgumentParser
에 대한 선택적 두 번째 인수가 있습니다. 예: argparse::ArgumentParser program("libfoo", "1.9.0");
참고: 기본 인수를 제어하는 ArgumentParser
에는 선택적인 세 번째 및 네 번째 인수가 있습니다. 예: argparse::ArgumentParser program("libfoo", "1.9.0", default_arguments::help, false);
아래의 기본 인수를 참조하세요.
새 인수를 추가하려면 .add_argument(...)
호출하면 됩니다. 함께 그룹화하려는 인수 이름의 가변 목록을 제공할 수 있습니다(예: -v
및 --verbose
.
program.add_argument( " foo " );
program.add_argument( " -v " , " --verbose " ); // parameter packing
Argparse는 위치 인수, 선택 인수, 복합 인수를 포함한 다양한 인수 유형을 지원합니다. 아래에서 이러한 각 유형을 구성하는 방법을 확인할 수 있습니다.
위치 인수 의 예는 다음과 같습니다.
# include < argparse/argparse.hpp >
int main ( int argc, char *argv[]) {
argparse::ArgumentParser program ( " program_name " );
program. add_argument ( " square " )
. help ( " display the square of a given integer " )
. scan < ' i ' , int >();
try {
program. parse_args (argc, argv);
}
catch ( const std:: exception & err) {
std::cerr << err. what () << std::endl;
std::cerr << program;
return 1 ;
}
auto input = program. get < int >( " square " );
std::cout << (input * input) << std::endl;
return 0 ;
}
그리고 코드를 실행하면:
foo@bar:/home/dev/ $ ./main 15
225
현재 상황은 다음과 같습니다.
add_argument()
메서드는 프로그램이 허용할 명령줄 옵션을 지정하는 데 사용됩니다. 이번 경우에는 기능에 맞게 사각형이라고 이름을 붙였습니다..scan
메서드를 사용하여 사용자 입력을 정수로 변환합니다.parser.get<T>(key)
메소드를 사용하여 주어진 인수에 대해 파서가 저장한 값을 얻을 수 있습니다. 이제 선택적 인수 를 살펴보겠습니다. 선택적 인수는 -
또는 --
로 시작합니다(예: --verbose
또는 -a
. 선택적 인수는 입력 시퀀스의 어느 위치에나 배치할 수 있습니다.
argparse::ArgumentParser program ( " test " );
program.add_argument( " --verbose " )
.help( " increase output verbosity " )
.default_value( false )
.implicit_value( true );
try {
program. parse_args (argc, argv);
}
catch ( const std:: exception & err) {
std::cerr << err. what () << std::endl;
std::cerr << program;
std::exit ( 1 );
}
if (program[ " --verbose " ] == true ) {
std::cout << " Verbosity enabled " << std::endl;
}
foo@bar:/home/dev/ $ ./main --verbose
Verbosity enabled
현재 상황은 다음과 같습니다.
--verbose
없이 프로그램을 실행할 때 오류가 발생하지 않습니다. .default_value(false)
를 사용하면 선택적 인수가 사용되지 않으면 해당 값이 자동으로 false로 설정됩니다..implicit_value(true)
사용하여 사용자는 이 옵션이 값을 요구하는 것보다 플래그에 가깝다는 것을 지정합니다. 사용자가 --verbose 옵션을 제공하면 해당 값이 true로 설정됩니다. 플래그 인수를 정의할 때 default_value(false).implicit_value(true)
와 동일한 단축형 flag()
사용할 수 있습니다.
argparse::ArgumentParser program ( " test " );
program.add_argument( " --verbose " )
.help( " increase output verbosity " )
.flag();
try {
program. parse_args (argc, argv);
}
catch ( const std:: exception & err) {
std::cerr << err. what () << std::endl;
std::cerr << program;
std::exit ( 1 );
}
if (program[ " --verbose " ] == true ) {
std::cout << " Verbosity enabled " << std::endl;
}
선택적 인수를 필수로 설정하려는 시나리오가 있습니다. 위에서 설명한 대로 선택적 인수는 -
또는 --
로 시작합니다. 다음과 같이 이러한 유형의 인수를 필수로 만들 수 있습니다.
program.add_argument( " -o " , " --output " )
.required()
.help( " specify the output file. " );
사용자가 이 매개변수에 대한 값을 제공하지 않으면 예외가 발생합니다.
또는 다음과 같이 기본값을 제공할 수 있습니다.
program.add_argument( " -o " , " --output " )
.default_value(std::string( " - " ))
.required()
.help( " specify the output file. " );
선택적 인수가 필요하지만 적절한 기본값이 없는 경우 다음과 같이 인수 테스트와 액세스를 결합할 수 있습니다.
if ( auto fn = program.present( " -o " )) {
do_something_with (*fn);
}
get
과 마찬가지로 present
메서드도 템플릿 인수를 허용합니다. 그러나 T
반환하는 대신, parser.present<T>(key)
std::optional<T>
반환하므로 사용자가 이 매개 변수에 값을 제공하지 않으면 반환 값은 std::nullopt
와 동일하게 비교됩니다.
사용자가 .default_value
가 있는 인수에 값을 제공했는지 알고 싶다면 인수가 .is_used()
인지 확인하세요.
program.add_argument( " --color " )
.default_value(std::string{ " orange " }) // might otherwise be type const char* leading to an error when trying program.get<std::string>
.help( " specify the cat's fur color " );
try {
program. parse_args (argc, argv); // Example: ./main --color orange
}
catch ( const std:: exception & err) {
std::cerr << err. what () << std::endl;
std::cerr << program;
std::exit ( 1 );
}
auto color = program.get<std::string>( " --color " ); // "orange"
auto explicit_color = program.is_used( " --color " ); // true, user provided orange
선택적 인수를 반복하여 모든 값을 한곳에 수집할 수 있습니다.
program.add_argument( " --color " )
.default_value<std::vector<std::string>>({ " orange " })
.append()
.help( " specify the cat's fur color " );
try {
program. parse_args (argc, argv); // Example: ./main --color red --color green --color blue
}
catch ( const std:: exception & err) {
std::cerr << err. what () << std::endl;
std::cerr << program;
std::exit ( 1 );
}
auto colors = program.get<std::vector<std::string>>( " --color " ); // {"red", "green", "blue"}
.default_value
에는 .get
하려는 유형과 일치하는 명시적인 템플릿 매개변수가 제공됩니다.
일반적인 패턴은 더 큰 값을 나타내기 위해 인수를 반복하는 것입니다.
int verbosity = 0 ;
program.add_argument( " -V " , " --verbose " )
.action([&]( const auto &) { ++verbosity; })
.append()
.default_value( false )
.implicit_value( true )
.nargs( 0 );
program.parse_args(argc, argv); // Example: ./main -VVVV
std::cout << " verbose level: " << verbosity << std::endl; // verbose level: 4
program.add_mutually_exclusive_group(required = false)
사용하여 상호 배타적인 그룹을 만듭니다. `argparse`는 상호 배타적인 그룹의 인수 중 하나만 명령줄에 있는지 확인합니다.
auto &group = program.add_mutually_exclusive_group();
group.add_argument( " --first " );
group.add_argument( " --second " );
다음과 같이 사용하면 오류가 발생합니다.
foo@bar:/home/dev/ $ ./main --first 1 --second 2
Argument '--second VAR' not allowed with '--first VAR'
add_mutually_exclusive_group()
함수는 required
인수도 허용하여 상호 배타적인 인수 중 하나 이상이 필요함을 나타냅니다.
auto &group = program.add_mutually_exclusive_group( true );
group.add_argument( " --first " );
group.add_argument( " --second " );
다음과 같이 사용하면 오류가 발생합니다.
foo@bar:/home/dev/ $ ./main
One of the arguments '--first VAR' or '--second VAR' is required
program.get<T>(arg_name)
또는 program[arg_name]
명시적으로 호출하는 대신 값을 저장하는 변수에 인수를 바인딩할 수 있습니다.
이는 현재 bool
유형(암시적으로 flag()
호출), int
, double
, std::string
, std::vector<std::string>
및 std::vector<int>
의 변수에 대해 구현됩니다. 인수가 명령줄에 지정되지 않은 경우 기본값(설정된 경우)이 변수에 설정됩니다.
bool flagvar = false ;
program.add_argument( " --flagvar " ).store_into(flagvar);
int intvar = 0 ;
program.add_argument( " --intvar " ).store_into(intvar);
double doublevar = 0 ;
program.add_argument( " --doublevar " ).store_into(doublevar);
std::string strvar;
program.add_argument( " --strvar " ).store_into(strvar);
std::vector<std::string> strvar_repeated;
program.add_argument( " --strvar-repeated " ).append().store_into(strvar_repeated);
std::vector<std::string> strvar_multi_valued;
program.add_argument( " --strvar-multi-valued " ).nargs( 2 ).store_into(strvar_multi_valued);
std::vector< int > intvar_repeated;
program.add_argument( " --intvar-repeated " ).append().store_into(intvar_repeated);
std::vector< int > intvar_multi_valued;
program.add_argument( " --intvar-multi-valued " ).nargs( 2 ).store_into(intvar_multi_valued);
선택적 인수는 -
로 시작합니다. argparse
음수를 처리할 수 있나요? 대답은 그렇습니다!
argparse::ArgumentParser program;
program.add_argument( " integer " )
.help( " Input number " )
.scan< ' i ' , int >();
program.add_argument( " floats " )
.help( " Vector of floats " )
.nargs( 4 )
.scan< ' g ' , float >();
try {
program. parse_args (argc, argv);
}
catch ( const std:: exception & err) {
std::cerr << err. what () << std::endl;
std::cerr << program;
std::exit ( 1 );
}
// Some code to print arguments
foo@bar:/home/dev/ $ ./main -5 -1.1 -3.1415 -3.1e2 -4.51329E3
integer : -5
floats : -1.1 -3.1415 -310 -4513.29
여기에서 볼 수 있듯이 argparse
음수, 음수 부동 소수점 및 과학적 표기법을 지원합니다.
argparse::ArgumentParser program ( " main " );
program.add_argument( " square " )
.help( " display the square of a given number " )
.scan< ' i ' , int >();
program.add_argument( " --verbose " )
.default_value( false )
.implicit_value( true );
try {
program. parse_args (argc, argv);
}
catch ( const std:: exception & err) {
std::cerr << err. what () << std::endl;
std::cerr << program;
std::exit ( 1 );
}
int input = program.get< int >( " square " );
if (program[ " --verbose " ] == true ) {
std::cout << " The square of " << input << " is " << (input * input) << std::endl;
}
else {
std::cout << (input * input) << std::endl;
}
foo@bar:/home/dev/ $ ./main 4
16
foo@bar:/home/dev/ $ ./main 4 --verbose
The square of 4 is 16
foo@bar:/home/dev/ $ ./main --verbose 4
The square of 4 is 16
std::cout << program
프로그램 사용법과 ArgumentParser
에 등록된 인수에 대한 정보를 포함한 도움말 메시지를 인쇄합니다. 이전 예의 기본 도움말 메시지는 다음과 같습니다.
foo@bar:/home/dev/$ ./main --help
Usage: main [-h] [--verbose] square
Positional arguments:
square display the square of a given number
Optional arguments:
-h, --help shows help message and exits
-v, --version prints version information and exits
--verbose
program.help().str()
통해 문자열로 도움말 메시지를 얻을 수도 있습니다.
ArgumentParser::add_description
자세한 인수 정보 앞에 텍스트를 추가합니다. ArgumentParser::add_epilog
다른 모든 도움말 출력 뒤에 텍스트를 추가합니다.
# include < argparse/argparse.hpp >
int main ( int argc, char *argv[]) {
argparse::ArgumentParser program ( " main " );
program. add_argument ( " thing " ). help ( " Thing to use. " ). metavar ( " THING " );
program. add_argument ( " --member " ). help ( " The alias for the member to pass to. " ). metavar ( " ALIAS " );
program. add_argument ( " --verbose " ). default_value ( false ). implicit_value ( true );
program. add_description ( " Forward a thing to the next member. " );
program. add_epilog ( " Possible things include betingalw, chiz, and res. " );
program. parse_args (argc, argv);
std::cout << program << std::endl;
}
Usage: main [-h] [--member ALIAS] [--verbose] THING
Forward a thing to the next member.
Positional arguments:
THING Thing to use.
Optional arguments:
-h, --help shows help message and exits
-v, --version prints version information and exits
--member ALIAS The alias for the member to pass to.
--verbose
Possible things include betingalw, chiz, and res.
ArgumentParser 개체는 일반적으로 단일 명령줄 인수를 수행할 단일 작업과 연결합니다. .nargs
는 다양한 수의 명령줄 인수를 단일 작업과 연결합니다. nargs(N)
사용하면 명령줄의 N 인수가 목록으로 함께 수집됩니다.
argparse::ArgumentParser program ( " main " );
program.add_argument( " --input_files " )
.help( " The list of input files " )
.nargs( 2 );
try {
program. parse_args (argc, argv); // Example: ./main --input_files config.yml System.xml
}
catch ( const std:: exception & err) {
std::cerr << err. what () << std::endl;
std::cerr << program;
std::exit ( 1 );
}
auto files = program.get<std::vector<std::string>>( " --input_files " ); // {"config.yml", "System.xml"}
ArgumentParser.get<T>()
std::vector
및 std::list
에 대한 특수화가 있습니다. 따라서 다음 변형인 .get<std::list>
도 작동합니다.
auto files = program.get<std::list<std::string>>( " --input_files " ); // {"config.yml", "System.xml"}
.scan
사용하면 명령줄 인수에서 원하는 값 유형 목록을 빠르게 작성할 수 있습니다. 예는 다음과 같습니다.
argparse::ArgumentParser program ( " main " );
program.add_argument( " --query_point " )
.help( " 3D query point " )
.nargs( 3 )
.default_value(std::vector< double >{ 0.0 , 0.0 , 0.0 })
.scan< ' g ' , double >();
try {
program. parse_args (argc, argv); // Example: ./main --query_point 3.5 4.7 9.2
}
catch ( const std:: exception & err) {
std::cerr << err. what () << std::endl;
std::cerr << program;
std::exit ( 1 );
}
auto query_point = program.get<std::vector< double >>( " --query_point " ); // {3.5, 4.7, 9.2}
.nargs
를 사용하여 가변 길이 인수 목록을 만들 수도 있습니다. 다음은 몇 가지 예입니다.
program.add_argument( " --input_files " )
.nargs( 1 , 3 ); // This accepts 1 to 3 arguments.
몇 가지 유용한 패턴은 Python에서 argparse의 "?", "*", "+"와 같이 정의됩니다.
program.add_argument( " --input_files " )
.nargs(argparse::nargs_pattern::any); // "*" in Python. This accepts any number of arguments including 0.
program.add_argument( " --input_files " )
.nargs(argparse::nargs_pattern::at_least_one); // "+" in Python. This accepts one or more number of arguments.
program.add_argument( " --input_files " )
.nargs(argparse::nargs_pattern::optional); // "?" in Python. This accepts an argument optionally.
복합 인수는 결합되어 단일 인수로 제공되는 선택적 인수입니다. 예: ps -aux
argparse::ArgumentParser program ( " test " );
program.add_argument( " -a " )
.default_value( false )
.implicit_value( true );
program.add_argument( " -b " )
.default_value( false )
.implicit_value( true );
program.add_argument( " -c " )
.nargs( 2 )
.default_value(std::vector< float >{ 0 . 0f , 0 . 0f })
.scan< ' g ' , float >();
try {
program. parse_args (argc, argv); // Example: ./main -abc 1.95 2.47
}
catch ( const std:: exception & err) {
std::cerr << err. what () << std::endl;
std::cerr << program;
std::exit ( 1 );
}
auto a = program.get< bool >( " -a " ); // true
auto b = program.get< bool >( " -b " ); // true
auto c = program.get<std::vector< float >>( " -c " ); // {1.95, 2.47}
// / Some code that prints parsed arguments
foo@bar:/home/dev/ $ ./main -ac 3.14 2.718
a = true
b = false
c = {3.14, 2.718}
foo@bar:/home/dev/ $ ./main -cb
a = false
b = true
c = {0.0, 0.0}
현재 상황은 다음과 같습니다.
-a
, -b
및 -c
가 있습니다.-a
및 -b
토글 인수입니다.-c
명령줄에서 2개의 부동 소수점 숫자가 필요합니다.-abc
-bac
또는 -cab
와 같은 복합 인수를 처리할 수 있습니다. 이는 짧은 단일 문자 인수 이름에만 작동합니다.-a
및 -b
true가 됩니다.-c
에 매핑된 입력을 식별하기 위해 추가로 구문 분석됩니다..default_value
에 정의된 대로 c의 기본값은 {0.0, 0.0}입니다.입력의 경우 사용자는 값에 대한 기본 유형을 표현할 수 있습니다.
.scan<Shape, T>
메서드는 Shape
변환 지정자에 따라 들어오는 std::string
T
로 변환하려고 시도합니다. 오류가 있는 경우 std::invalid_argument
또는 std::range_error
예외가 발생합니다.
program.add_argument( " -x " )
.scan< ' d ' , int >();
program.add_argument( " scale " )
.scan< ' g ' , double >();
Shape
입력의 "모양"을 지정하고 유형 템플릿 인수는 미리 정의된 작업의 반환 값을 지정합니다. 허용되는 유형은 부동 소수점(예: float, double, long double) 및 정수(예: signed char, short, int, long, long long)입니다.
문법은 std::from_chars
따르지만 정확하게 복제하지는 않습니다. 예를 들어, 16진수 숫자는 0x
또는 0X
로 시작할 수 있으며 앞에 0이 있는 숫자는 8진수 값으로 처리될 수 있습니다.
모양 | 해석 |
---|---|
'a' 또는 'A' | 16진수 부동 소수점 |
'e' 또는 'E' | 과학적 표기법(부동 소수점) |
'f' 또는 'F' | 고정 표기법(부동 소수점) |
'g' 또는 'G' | 일반 형식(고정 또는 과학적) |
'디' | 소수 |
'나' | std::from_chars 기본 == 10인 문법 |
'영형' | 8진수(부호 없음) |
'유' | 10진수(부호 없음) |
'x' 또는 'X' | 16진수(부호 없음) |
argparse
-h
/ --help
및 -v
/ --version
에 대해 사전 정의된 인수와 작업을 제공합니다. 기본적으로 이러한 작업은 각각 도움말이나 버전 메시지를 표시한 후 프로그램을 종료 합니다. 이 종료는 소멸자를 호출하지 않고 가져온 리소스 정리를 건너뜁니다.
이러한 기본 인수는 ArgumentParser
생성 중에 비활성화될 수 있으므로 이러한 인수를 원하는 방식으로 처리할 수 있습니다. (기본 인수를 선택할 때 프로그램 이름과 버전을 포함해야 합니다.)
argparse::ArgumentParser program ( " test " , " 1.0 " , default_arguments::none);
program.add_argument( " -h " , " --help " )
.action([=]( const std::string& s) {
std::cout << help (). str ();
})
.default_value( false )
.help( " shows help message " )
.implicit_value( true )
.nargs( 0 );
위의 코드 조각은 도움말 메시지를 출력하고 계속 실행됩니다. --version
인수를 지원하지 않습니다.
포함된 인수의 기본값은 default_arguments::all
입니다. default_arguments::none
에는 기본 인수가 추가되지 않습니다. default_arguments::help
및 default_arguments::version
--help
및 --version
개별적으로 추가합니다.
이러한 인수를 사용하여 기본 종료를 비활성화하는 동안 기본 인수를 사용할 수 있습니다. ArgumentParser
( exit_on_default_arguments
)에 대한 이 네 번째 인수는 기본 true 값을 갖는 부울 플래그입니다. 다음 호출은 --help
및 --version
유지하지만 해당 인수가 사용될 때 종료되지 않습니다.
argparse::ArgumentParser program ( " test " , " 1.0 " , default_arguments::all, false )
argparse
예를 들어 컴파일러에서 사용하기 위해 명령 끝에서 "나머지" 인수 수집을 지원합니다.
foo@bar:/home/dev/ $ compiler file1 file2 file3
이를 활성화하려면 인수를 생성하고 remaining
것으로 표시하면 됩니다. argparse에 전달된 나머지 모든 인수는 여기에 수집됩니다.
argparse::ArgumentParser program ( " compiler " );
program.add_argument( " files " )
.remaining();
try {
program. parse_args (argc, argv);
}
catch ( const std:: exception & err) {
std::cerr << err. what () << std::endl;
std::cerr << program;
std::exit ( 1 );
}
try {
auto files = program. get <std::vector<std::string>>( " files " );
std::cout << files. size () << " files provided " << std::endl;
for ( auto & file : files)
std::cout << file << std::endl;
} catch (std::logic_error& e) {
std::cout << " No files provided " << std::endl;
}
인수가 제공되지 않은 경우:
foo@bar:/home/dev/ $ ./compiler
No files provided
여러 인수가 제공되는 경우:
foo@bar:/home/dev/ $ ./compiler foo.txt bar.txt baz.txt
3 files provided
foo.txt
bar.txt
baz.txt
나머지 인수를 수집하는 프로세스는 선택적 인수와도 잘 작동합니다.