option=value
Cukup sertakan argparse.hpp dan Anda siap melakukannya.
# include < argparse/argparse.hpp >
Untuk mulai menguraikan argumen baris perintah, buat ArgumentParser
.
argparse::ArgumentParser program ( " program_name " );
CATATAN: Ada argumen opsional kedua pada ArgumentParser
yang merupakan versi program. Contoh: argparse::ArgumentParser program("libfoo", "1.9.0");
CATATAN: Ada argumen opsional ketiga dan keempat pada ArgumentParser
yang mengontrol argumen default. Contoh: argparse::ArgumentParser program("libfoo", "1.9.0", default_arguments::help, false);
Lihat Argumen Default di bawah.
Untuk menambahkan argumen baru, cukup panggil .add_argument(...)
. Anda dapat memberikan daftar nama argumen variadik yang ingin Anda kelompokkan, misalnya -v
dan --verbose
program.add_argument( " foo " );
program.add_argument( " -v " , " --verbose " ); // parameter packing
Argparse mendukung berbagai tipe argumen termasuk argumen posisi, opsional, dan gabungan. Di bawah ini Anda dapat melihat cara mengonfigurasi masing-masing jenis ini:
Berikut ini contoh argumen posisi :
# 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 ;
}
Dan menjalankan kode:
foo@bar:/home/dev/ $ ./main 15
225
Inilah yang terjadi:
add_argument()
digunakan untuk menentukan opsi baris perintah mana yang dapat diterima oleh program. Dalam hal ini saya beri nama persegi agar sesuai dengan fungsinya..scan
untuk mengubah input pengguna menjadi bilangan bulat.parser.get<T>(key)
. Sekarang, mari kita lihat argumen opsional . Argumen opsional dimulai dengan -
atau --
, misalnya --verbose
atau -a
. Argumen opsional dapat ditempatkan di mana saja dalam urutan masukan.
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
Inilah yang terjadi:
--verbose
. Perhatikan bahwa dengan menggunakan .default_value(false)
, jika argumen opsional tidak digunakan, nilainya secara otomatis disetel ke false..implicit_value(true)
, pengguna menentukan bahwa opsi ini lebih merupakan tanda daripada sesuatu yang memerlukan nilai. Saat pengguna memberikan opsi --verbose, nilainya disetel ke true. Saat mendefinisikan argumen flag, Anda dapat menggunakan singkatan flag()
yang sama dengan default_value(false).implicit_value(true)
.
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;
}
Ada beberapa skenario di mana Anda ingin membuat argumen opsional diperlukan . Seperti dibahas di atas, argumen opsional dimulai dengan -
atau --
. Anda dapat membuat argumen jenis ini diperlukan seperti:
program.add_argument( " -o " , " --output " )
.required()
.help( " specify the output file. " );
Jika pengguna tidak memberikan nilai untuk parameter ini, pengecualian akan diberikan.
Alternatifnya, Anda dapat memberikan nilai default seperti ini:
program.add_argument( " -o " , " --output " )
.default_value(std::string( " - " ))
.required()
.help( " specify the output file. " );
Jika Anda memerlukan argumen opsional untuk ada tetapi tidak memiliki nilai default yang baik, Anda dapat menggabungkan pengujian dan mengakses argumen sebagai berikut:
if ( auto fn = program.present( " -o " )) {
do_something_with (*fn);
}
Mirip dengan get
, metode present
juga menerima argumen templat. Namun alih-alih mengembalikan T
, parser.present<T>(key)
mengembalikan std::optional<T>
, sehingga ketika pengguna tidak memberikan nilai ke parameter ini, nilai yang dikembalikan sebanding dengan std::nullopt
.
Jika Anda ingin mengetahui apakah pengguna memberikan nilai untuk argumen yang memiliki .default_value
, periksa apakah argumen tersebut .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
Anda mungkin ingin mengizinkan argumen opsional diulang dan mengumpulkan semua nilai di satu tempat.
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"}
Perhatikan bahwa .default_value
diberikan parameter templat eksplisit untuk mencocokkan jenis yang Anda inginkan .get
.
Pola yang umum adalah mengulangi argumen untuk menunjukkan nilai yang lebih besar.
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
Buat grup yang saling eksklusif menggunakan program.add_mutually_exclusive_group(required = false)
. `argparse`` akan memastikan bahwa hanya satu argumen dalam grup saling eksklusif yang ada di baris perintah:
auto &group = program.add_mutually_exclusive_group();
group.add_argument( " --first " );
group.add_argument( " --second " );
dengan penggunaan berikut akan menghasilkan kesalahan:
foo@bar:/home/dev/ $ ./main --first 1 --second 2
Argument '--second VAR' not allowed with '--first VAR'
Fungsi add_mutually_exclusive_group()
juga menerima argumen required
, untuk menunjukkan bahwa setidaknya satu argumen yang saling eksklusif diperlukan:
auto &group = program.add_mutually_exclusive_group( true );
group.add_argument( " --first " );
group.add_argument( " --second " );
dengan penggunaan berikut akan menghasilkan kesalahan:
foo@bar:/home/dev/ $ ./main
One of the arguments '--first VAR' or '--second VAR' is required
Dimungkinkan untuk mengikat argumen ke variabel yang menyimpan nilainya, sebagai alternatif untuk memanggil program.get<T>(arg_name)
atau program[arg_name]
secara eksplisit
Ini saat ini diterapkan untuk variabel bertipe bool
(ini juga secara implisit memanggil flag()
), int
, double
, std::string
, std::vector<std::string>
dan std::vector<int>
. Jika argumen tidak ditentukan di baris perintah, nilai default (jika disetel) diatur ke dalam variabel.
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);
Argumen opsional dimulai dengan -
. Bisakah argparse
menangani angka negatif? Jawabannya adalah ya!
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
Seperti yang Anda lihat di sini, argparse
mendukung bilangan bulat negatif, float negatif, dan notasi ilmiah.
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
mencetak pesan bantuan, termasuk penggunaan program dan informasi tentang argumen yang didaftarkan pada ArgumentParser
. Untuk contoh sebelumnya, inilah pesan bantuan default:
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
Anda juga bisa mendapatkan pesan bantuan dalam bentuk string melalui program.help().str()
.
ArgumentParser::add_description
akan menambahkan teks sebelum informasi argumen terperinci. ArgumentParser::add_epilog
akan menambahkan teks setelah semua keluaran bantuan lainnya.
# 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.
Objek ArgumentParser biasanya mengaitkan satu argumen baris perintah dengan satu tindakan yang harus diambil. .nargs
mengaitkan sejumlah argumen baris perintah yang berbeda dengan satu tindakan. Saat menggunakan nargs(N)
, N argumen dari baris perintah akan dikumpulkan menjadi sebuah daftar.
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>()
memiliki spesialisasi untuk std::vector
dan std::list
. Jadi, varian berikut, .get<std::list>
, juga akan berfungsi.
auto files = program.get<std::list<std::string>>( " --input_files " ); // {"config.yml", "System.xml"}
Dengan menggunakan .scan
, seseorang dapat dengan cepat membuat daftar tipe nilai yang diinginkan dari argumen baris perintah. Berikut ini contohnya:
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}
Anda juga dapat membuat daftar argumen dengan panjang variabel dengan .nargs
. Di bawah ini beberapa contohnya.
program.add_argument( " --input_files " )
.nargs( 1 , 3 ); // This accepts 1 to 3 arguments.
Beberapa pola berguna didefinisikan seperti "?", "*", "+" dari argparse dengan Python.
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.
Argumen gabungan adalah argumen opsional yang digabungkan dan disediakan sebagai satu argumen. Contoh: 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}
Inilah yang terjadi:
-a
, -b
dan -c
.-a
dan -b
adalah argumen sakelar.-c
membutuhkan 2 angka floating point dari baris perintah.-abc
atau -bac
atau -cab
. Ini hanya berfungsi dengan nama argumen pendek berkarakter tunggal.-a
dan -b
menjadi kenyataan.-c
..default_value
Untuk masukan, pengguna dapat mengekspresikan tipe primitif untuk nilai tersebut.
Metode .scan<Shape, T>
mencoba mengonversi std::string
yang masuk ke T
mengikuti penentu konversi Shape
. Pengecualian std::invalid_argument
atau std::range_error
dilemparkan untuk kesalahan.
program.add_argument( " -x " )
.scan< ' d ' , int >();
program.add_argument( " scale " )
.scan< ' g ' , double >();
Shape
menentukan "tampilan" masukan, dan argumen templat tipe menentukan nilai kembalian dari tindakan yang telah ditentukan sebelumnya. Tipe yang dapat diterima adalah floating point (yaitu float, double, long double) dan integral (yaitu karakter bertanda, short, int, long, long long).
Tata bahasanya mengikuti std::from_chars
, tetapi tidak persis menduplikasinya. Misalnya, bilangan heksadesimal dapat dimulai dengan 0x
atau 0X
dan bilangan dengan nol di depannya dapat dianggap sebagai nilai oktal.
Membentuk | interpretasi |
---|---|
'a' atau 'A' | titik mengambang heksadesimal |
'e' atau 'E' | notasi ilmiah (floating point) |
'f' atau 'F' | notasi tetap (floating point) |
'g' atau 'G' | bentuk umum (baik tetap atau ilmiah) |
'D' | desimal |
'Saya' | std::from_chars tata bahasa dengan basis == 10 |
'Hai' | oktal (tidak ditandatangani) |
'kamu' | desimal (tidak ditandatangani) |
'x' atau 'X' | heksadesimal (tidak ditandatangani) |
argparse
memberikan argumen dan tindakan yang telah ditentukan sebelumnya untuk -h
/ --help
dan -v
/ --version
. Secara default, tindakan ini akan keluar dari program setelah menampilkan pesan bantuan atau versi. Pintu keluar ini tidak memanggil destruktor, melewatkan pembersihan sumber daya yang diambil.
Argumen default ini dapat dinonaktifkan selama pembuatan ArgumentParser
sehingga Anda dapat menangani argumen ini dengan cara Anda sendiri. (Perhatikan bahwa nama dan versi program harus disertakan saat memilih argumen default.)
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 );
Cuplikan kode di atas mengeluarkan pesan bantuan dan terus berjalan. Itu tidak mendukung argumen --version
.
Standarnya adalah default_arguments::all
untuk argumen yang disertakan. Tidak ada argumen default yang akan ditambahkan dengan default_arguments::none
. default_arguments::help
dan default_arguments::version
akan menambahkan --help
dan --version
satu per satu.
Argumen default dapat digunakan sambil menonaktifkan keluar default dengan argumen ini. Argumen keempat untuk ArgumentParser
( exit_on_default_arguments
) ini adalah tanda bool dengan nilai default sebenarnya . Panggilan berikut akan mempertahankan --help
dan --version
, namun tidak akan keluar ketika argumen tersebut digunakan.
argparse::ArgumentParser program ( " test " , " 1.0 " , default_arguments::all, false )
argparse
mendukung pengumpulan argumen "yang tersisa" di akhir perintah, misalnya, untuk digunakan dalam kompiler:
foo@bar:/home/dev/ $ compiler file1 file2 file3
Untuk mengaktifkannya, cukup buat argumen dan tandai sebagai remaining
. Semua argumen tersisa yang diteruskan ke argparse dikumpulkan di sini.
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;
}
Ketika tidak ada argumen yang diberikan:
foo@bar:/home/dev/ $ ./compiler
No files provided
dan ketika beberapa argumen diberikan:
foo@bar:/home/dev/ $ ./compiler foo.txt bar.txt baz.txt
3 files provided
foo.txt
bar.txt
baz.txt
Proses mengumpulkan argumen yang tersisa juga berfungsi baik dengan argumen opsional: