前言:
此刻同学们对“c语言命令行参数解析”大概比较注重,看官们都需要分析一些“c语言命令行参数解析”的相关内容。那么小编在网摘上收集了一些关于“c语言命令行参数解析””的相关内容,希望咱们能喜欢,朋友们一起来了解一下吧!概述
命令行参数解析,在写一些命令行的程序时需要用到,args.hxx类似于Python的argparse,但在C++中,它具有静态类型检查,并且速度更快(也允许完全嵌套的组逻辑,而Python的argparse没有),支持自定义类型解析,子命令等。使用上,只需要在工程中include “args.hxx” 就可以正常使用,符合C++11规范,兼容性更好。
文档和源码
API文档地址:
源码地址: at
范例
以下的所有代码示例都将是完整的代码示例,并带有一些输出。
简单范例
#include <iostream>#include <args.hxx>int main(int argc, char **argv){ args::ArgumentParser parser("This is a test program.", "This goes after the options."); args::HelpFlag help(parser, "help", "Display this help menu", {'h', "help"}); args::CompletionFlag completion(parser, {"complete"}); try { parser.ParseCLI(argc, argv); } catch (const args::Completion& e) { std::cout << e.what(); return 0; } catch (const args::Help&) { std::cout << parser; return 0; } catch (const args::ParseError& e) { std::cerr << e.what() << std::endl; std::cerr << parser; return 1; } return 0;}
运行输出:
% ./test % ./test -h ./test {OPTIONS} This is a test program. OPTIONS: -h, --help Display this help menu This goes after the options. %布尔标志、特殊组类型、不同的匹配器构造
#include <iostream>#include <args.hxx>int main(int argc, char **argv){ args::ArgumentParser parser("This is a test program.", "This goes after the options."); args::Group group(parser, "This group is all exclusive:", args::Group::Validators::Xor); args::Flag foo(group, "foo", "The foo flag", {'f', "foo"}); args::Flag bar(group, "bar", "The bar flag", {'b'}); args::Flag baz(group, "baz", "The baz flag", {"baz"}); try { parser.ParseCLI(argc, argv); } catch (args::Help) { std::cout << parser; return 0; } catch (args::ParseError e) { std::cerr << e.what() << std::endl; std::cerr << parser; return 1; } catch (args::ValidationError e) { std::cerr << e.what() << std::endl; std::cerr << parser; return 1; } if (foo) { std::cout << "foo" << std::endl; } if (bar) { std::cout << "bar" << std::endl; } if (baz) { std::cout << "baz" << std::endl; } return 0;}
运行输出:
% ./test Group validation failed somewhere! ./test {OPTIONS} This is a test program. OPTIONS: This group is all exclusive: -f, --foo The foo flag -b The bar flag --baz The baz flag This goes after the options. % ./test -ffoo % ./test --foofoo % ./test --foo -ffoo % ./test -b bar % ./test --bazbaz % ./test --baz -fGroup validation failed somewhere! ./test {OPTIONS} This is a test program. ... % ./test --baz -fbGroup validation failed somewhere! ./test {OPTIONS} ... %参数标志、位置参数、列表
#include <iostream>#include <args.hxx>int main(int argc, char **argv){ args::ArgumentParser parser("This is a test program.", "This goes after the options."); args::HelpFlag help(parser, "help", "Display this help menu", {'h', "help"}); args::ValueFlag<int> integer(parser, "integer", "The integer flag", {'i'}); args::ValueFlagList<char> characters(parser, "characters", "The character flag", {'c'}); args::Positional<std::string> foo(parser, "foo", "The foo position"); args::PositionalList<double> numbers(parser, "numbers", "The numbers position list"); try { parser.ParseCLI(argc, argv); } catch (args::Help) { std::cout << parser; return 0; } catch (args::ParseError e) { std::cerr << e.what() << std::endl; std::cerr << parser; return 1; } catch (args::ValidationError e) { std::cerr << e.what() << std::endl; std::cerr << parser; return 1; } if (integer) { std::cout << "i: " << args::get(integer) << std::endl; } if (characters) { for (const auto ch: args::get(characters)) { std::cout << "c: " << ch << std::endl; } } if (foo) { std::cout << "f: " << args::get(foo) << std::endl; } if (numbers) { for (const auto nm: args::get(numbers)) { std::cout << "n: " << nm << std::endl; } } return 0;}
运行输出:
% ./test -h ./test {OPTIONS} [foo] [numbers...] This is a test program. OPTIONS: -h, --help Display this help menu -i integer The integer flag -c characters The character flag foo The foo position numbers The numbers position list "--" can be used to terminate flag options and force all following arguments to be treated as positional options This goes after the options. % ./test -i 5i: 5 % ./test -i 5.2Argument 'integer' received invalid value type '5.2' ./test {OPTIONS} [foo] [numbers...] % ./test -c 1 -c 2 -c 3c: 1c: 2c: 3 % % ./test 1 2 3 4 5 6 7 8 9f: 1n: 2n: 3n: 4n: 5n: 6n: 7n: 8n: 9 % ./test 1 2 3 4 5 6 7 8 9 aArgument 'numbers' received invalid value type 'a' ./test {OPTIONS} [foo] [numbers...] This is a test program. ...命令行子命令
#include <iostream>#include <args.hxx>int main(int argc, char **argv){ args::ArgumentParser p("git-like parser"); args::Group commands(p, "commands"); args::Command add(commands, "add", "add file contents to the index"); args::Command commit(commands, "commit", "record changes to the repository"); args::Group arguments(p, "arguments", args::Group::Validators::DontCare, args::Options::Global); args::ValueFlag<std::string> gitdir(arguments, "path", "", {"git-dir"}); args::HelpFlag h(arguments, "help", "help", {'h', "help"}); args::PositionalList<std::string> pathsList(arguments, "paths", "files to commit"); try { p.ParseCLI(argc, argv); if (add) { std::cout << "Add"; } else { std::cout << "Commit"; } for (auto &&path : pathsList) { std::cout << ' ' << path; } std::cout << std::endl; } catch (args::Help) { std::cout << p; } catch (args::Error& e) { std::cerr << e.what() << std::endl << p; return 1; } return 0;}
运行输出:
% ./test -h ./test COMMAND [paths...] {OPTIONS} git-like parser OPTIONS: commands add add file contents to the index commit record changes to the repository arguments --git-dir=[path] -h, --help help paths... files "--" can be used to terminate flag options and force all following arguments to be treated as positional options% ./test add 1 2Add 1 2重构子命令
#include <iostream>#include "args.hxx"args::Group arguments("arguments");args::ValueFlag<std::string> gitdir(arguments, "path", "", {"git-dir"});args::HelpFlag h(arguments, "help", "help", {'h', "help"});args::PositionalList<std::string> pathsList(arguments, "paths", "files to commit");void CommitCommand(args::Subparser &parser){ args::ValueFlag<std::string> message(parser, "MESSAGE", "commit message", {'m'}); parser.Parse(); std::cout << "Commit"; for (auto &&path : pathsList) { std::cout << ' ' << path; } std::cout << std::endl; if (message) { std::cout << "message: " << args::get(message) << std::endl; }}int main(int argc, const char **argv){ args::ArgumentParser p("git-like parser"); args::Group commands(p, "commands"); args::Command add(commands, "add", "add file contents to the index", [&](args::Subparser &parser) { parser.Parse(); std::cout << "Add"; for (auto &&path : pathsList) { std::cout << ' ' << path; } std::cout << std::endl; }); args::Command commit(commands, "commit", "record changes to the repository", &CommitCommand); args::GlobalOptions globals(p, arguments); try { p.ParseCLI(argc, argv); } catch (args::Help) { std::cout << p; } catch (args::Error& e) { std::cerr << e.what() << std::endl << p; return 1; } return 0;}
运行结果:
% ./test -h ./test COMMAND [paths...] {OPTIONS} git-like parser OPTIONS: commands add add file contents to the index commit record changes to the repository arguments --git-dir=[path] -h, --help help paths... files "--" can be used to terminate flag options and force all following arguments to be treated as positional options% ./test add 1 2Add 1 2% ./test commit -m "my commit message" 1 2Commit 1 2message: my commit message自定义类型解析器
这里我们使用std::tuple
#include <iostream>#include <tuple>std::istream& operator>>(std::istream& is, std::tuple<int, int>& ints){ is >> std::get<0>(ints); is.get(); is >> std::get<1>(ints); return is;}#include <args.hxx>struct DoublesReader{ void operator()(const std::string &name, const std::string &value, std::tuple<double, double> &destination) { size_t commapos = 0; std::get<0>(destination) = std::stod(value, &commapos); std::get<1>(destination) = std::stod(std::string(value, commapos + 1)); }};int main(int argc, char **argv){ args::ArgumentParser parser("This is a test program."); args::Positional<std::tuple<int, int>> ints(parser, "INTS", "This takes a pair of integers."); args::Positional<std::tuple<double, double>, DoublesReader> doubles(parser, "DOUBLES", "This takes a pair of doubles."); try { parser.ParseCLI(argc, argv); } catch (args::Help) { std::cout << parser; return 0; } catch (args::ParseError e) { std::cerr << e.what() << std::endl; std::cerr << parser; return 1; } if (ints) { std::cout << "ints found: " << std::get<0>(args::get(ints)) << " and " << std::get<1>(args::get(ints)) << std::endl; } if (doubles) { std::cout << "doubles found: " << std::get<0>(args::get(doubles)) << " and " << std::get<1>(args::get(doubles)) << std::endl; } return 0;}
运行输出:
% ./test -hArgument could not be matched: 'h' ./test [INTS] [DOUBLES] This is a test program. OPTIONS: INTS This takes a pair of integers. DOUBLES This takes a pair of doubles. % ./test 5ints found: 5 and 0 % ./test 5,8ints found: 5 and 8 % ./test 5,8 2.4,8ints found: 5 and 8doubles found: 2.4 and 8 % ./test 5,8 2.4, terminate called after throwing an instance of 'std::invalid_argument' what(): stodzsh: abort ./test 5,8 2.4, % ./test 5,8 2.4 terminate called after throwing an instance of 'std::out_of_range' what(): basic_string::basic_string: __pos (which is 4) > this->size() (which is 3)zsh: abort ./test 5,8 2.4 % ./test 5,8 2.4-7ints found: 5 and 8doubles found: 2.4 and 7 % ./test 5,8 2.4,-7ints found: 5 and 8doubles found: 2.4 and -7
更多范例请参考github上的手册:
版权声明:
本站文章均来自互联网搜集,如有侵犯您的权益,请联系我们删除,谢谢。
标签: #c语言命令行参数解析