Tôi muốn chuyển các tham số cho chương trình C ++ của mình theo cách sau:
./myprog --setting=value
Có thư viện nào giúp tôi thực hiện việc này một cách dễ dàng không?
Xem thêm Trình trợ giúp phân tích cú pháp đối số cho C và Unix
Tôi muốn chuyển các tham số cho chương trình C ++ của mình theo cách sau:
./myprog --setting=value
Có thư viện nào giúp tôi thực hiện việc này một cách dễ dàng không?
Xem thêm Trình trợ giúp phân tích cú pháp đối số cho C và Unix
Câu trả lời:
options.add_options()(option1)(option2)...
mà tôi coi là lạm dụng ngữ pháp C ++.
--long-option
, bạn hãy tự mình làm khá đơn giản.
boost::program_options
được khai thác quá mức, khó sử dụng và không có tài liệu. Một trong số ít các thư viện Boost sẽ được hưởng lợi rất nhiều từ việc thiết kế lại và viết lại hoàn toàn. Đừng sử dụng nó nếu bạn có thể tránh nó.
GNU GetOpt .
Một ví dụ đơn giản sử dụng GetOpt:
// C/C++ Libraries:
#include <string>
#include <iostream>
#include <unistd.h>
// Namespaces:
using namespace std;
int main(int argc, char** argv) {
int opt;
bool flagA = false;
bool flagB = false;
// Shut GetOpt error messages down (return '?'):
opterr = 0;
// Retrieve the options:
while ( (opt = getopt(argc, argv, "ab")) != -1 ) { // for each option...
switch ( opt ) {
case 'a':
flagA = true;
break;
case 'b':
flagB = true;
break;
case '?': // unknown option...
cerr << "Unknown option: '" << char(optopt) << "'!" << endl;
break;
}
}
// Debug:
cout << "flagA = " << flagA << endl;
cout << "flagB = " << flagB << endl;
return 0;
}
Bạn cũng có thể sử dụng optarg nếu bạn có các tùy chọn chấp nhận đối số.
Tôi thấy sử dụng ezOptionParser dễ dàng hơn . Nó cũng là một tệp tiêu đề duy nhất, không phụ thuộc vào bất kỳ thứ gì ngoài STL, hoạt động cho Windows và Linux (rất có thể là các nền tảng khác), không có đường cong học tập nhờ các ví dụ, có các tính năng mà các thư viện khác không có (như nhập / xuất tệp với nhận xét, tên tùy chọn tùy ý với dấu phân cách, định dạng sử dụng tự động, v.v.) và được cấp phép LGPL.
TCLAP
là một thiết kế nhẹ thực sự đẹp và dễ sử dụng:
http://tclap.sourceforge.net/
Và có một thư viện Google .
Thực sự, phân tích cú pháp dòng lệnh đã được "giải quyết". Chỉ cần chọn một.
Tôi nghĩ rằng GNU GetOpt không phải là quá ngay để sử dụng.
Qt và Boost có thể là một giải pháp, nhưng bạn cần tải xuống và biên dịch rất nhiều mã.
Vì vậy, tôi đã tự mình triển khai một trình phân tích cú pháp tạo ra một tham số std :: map <std :: string, std :: string>.
Ví dụ: gọi:
./myProgram -v -p 1234
bản đồ sẽ là:
["-v"][""]
["-p"]["1234"]
Cách sử dụng là:
int main(int argc, char *argv[]) {
MainOptions mo(argc, argv);
MainOptions::Option* opt = mo.getParamFromKey("-p");
const string type = opt ? (*opt).second : "";
cout << type << endl; /* Prints 1234 */
/* Your check code */
}
MainOptions.h
#ifndef MAINOPTIONS_H_
#define MAINOPTIONS_H_
#include <map>
#include <string>
class MainOptions {
public:
typedef std::pair<std::string, std::string> Option;
MainOptions(int argc, char *argv[]);
virtual ~MainOptions();
std::string getAppName() const;
bool hasKey(const std::string&) const;
Option* getParamFromKey(const std::string&) const;
void printOptions() const;
private:
typedef std::map<std::string, std::string> Options;
void parse();
const char* const *begin() const;
const char* const *end() const;
const char* const *last() const;
Options options_;
int argc_;
char** argv_;
std::string appName_;
};
MainOptions.cpp
#include "MainOptions.h"
#include <iostream>
using namespace std;
MainOptions::MainOptions(int argc, char* argv[]) :
argc_(argc),
argv_(argv) {
appName_ = argv_[0];
this->parse();
}
MainOptions::~MainOptions() {
}
std::string MainOptions::getAppName() const {
return appName_;
}
void MainOptions::parse() {
typedef pair<string, string> Option;
Option* option = new pair<string, string>();
for (const char* const * i = this->begin() + 1; i != this->end(); i++) {
const string p = *i;
if (option->first == "" && p[0] == '-') {
option->first = p;
if (i == this->last()) {
options_.insert(Option(option->first, option->second));
}
continue;
} else if (option->first != "" && p[0] == '-') {
option->second = "null"; /* or leave empty? */
options_.insert(Option(option->first, option->second));
option->first = p;
option->second = "";
if (i == this->last()) {
options_.insert(Option(option->first, option->second));
}
continue;
} else if (option->first != "") {
option->second = p;
options_.insert(Option(option->first, option->second));
option->first = "";
option->second = "";
continue;
}
}
}
void MainOptions::printOptions() const {
std::map<std::string, std::string>::const_iterator m = options_.begin();
int i = 0;
if (options_.empty()) {
cout << "No parameters\n";
}
for (; m != options_.end(); m++, ++i) {
cout << "Parameter [" << i << "] [" << (*m).first << " " << (*m).second
<< "]\n";
}
}
const char* const *MainOptions::begin() const {
return argv_;
}
const char* const *MainOptions::end() const {
return argv_ + argc_;
}
const char* const *MainOptions::last() const {
return argv_ + argc_ - 1;
}
bool MainOptions::hasKey(const std::string& key) const {
return options_.find(key) != options_.end();
}
MainOptions::Option* MainOptions::getParamFromKey(
const std::string& key) const {
const Options::const_iterator i = options_.find(key);
MainOptions::Option* o = 0;
if (i != options_.end()) {
o = new MainOptions::Option((*i).first, (*i).second);
}
return o;
}
Nếu có thể, tôi cũng khuyên bạn nên xem qua thư viện phân tích cú pháp tùy chọn mà tôi đã viết: dropt .
Một tính năng mà nó cung cấp mà nhiều người khác không có là khả năng ghi đè các tùy chọn trước đó. Ví dụ: nếu bạn có bí danh shell:
alias bar="foo --flag1 --flag2 --flag3"
và bạn muốn sử dụng bar
nhưng --flag1
bị vô hiệu hóa, nó cho phép bạn thực hiện:
bar --flag1=0
Qt 5.2 đi kèm với API phân tích cú pháp dòng lệnh .
Ví dụ nhỏ:
#include <QCoreApplication>
#include <QCommandLineParser>
#include <QDebug>
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
app.setApplicationName("ToolX");
app.setApplicationVersion("1.2");
QCommandLineParser parser;
parser.setApplicationDescription("Tool for doing X.");
parser.addHelpOption();
parser.addVersionOption();
parser.addPositionalArgument("infile",
QCoreApplication::translate("main", "Input file."));
QCommandLineOption verbose_opt("+",
QCoreApplication::translate("main", "be verbose"));
parser.addOption(verbose_opt);
QCommandLineOption out_opt(QStringList() << "o" << "output",
QCoreApplication::translate("main", "Output file."),
QCoreApplication::translate("main", "filename"), // value name
QCoreApplication::translate("main", "out") // default value
);
parser.addOption(out_opt);
// exits on error
parser.process(app);
const QStringList args = parser.positionalArguments();
qDebug() << "Input files: " << args
<< ", verbose: " << parser.isSet(verbose_opt)
<< ", output: " << parser.value(out_opt)
<< '\n';
return 0;
}
Màn hình trợ giúp được tạo tự động:
$ ./qtopt -h Cách sử dụng: ./qtopt [options] infile Công cụ để làm X. Các tùy chọn: -h, --help Hiển thị trợ giúp này. -v, --version Hiển thị thông tin phiên bản. - + dài dòng -o, --output Tập tin đầu ra. Tranh luận: infile Tập tin đầu vào.
Đầu ra phiên bản được tạo tự động:
$ ./qtopt -v ToolX 1.2
Một số cuộc gọi thực tế:
$ ./qtopt b1 - + -o tmp blah.foo Tệp đầu vào: ("b1", "blah.foo"), verbose: true, output: "tmp" $ ./qtopt Tệp đầu vào: (), verbose: false, đầu ra: "out"
Một lỗi phân tích cú pháp:
$ ./qtopt --hlp Tùy chọn không xác định 'hlp'. $ echo $? 1
Nếu chương trình của bạn đã sử dụng các thư viện Qt (> = 5.2), thì API phân tích cú pháp dòng lệnh của nó đủ thuận tiện để hoàn thành công việc.
Hãy lưu ý rằng các tùy chọn Qt tích hợp được sử dụng QApplication
trước khi trình phân tích cú pháp tùy chọn chạy.
argstream
khá giống với boost.program_option
: nó cho phép liên kết các biến với các tùy chọn, v.v. Tuy nhiên, nó không xử lý các tùy chọn được lưu trữ trong tệp cấu hình.
Hãy thử thư viện CLPP. Đây là thư viện đơn giản và linh hoạt để phân tích cú pháp các tham số dòng lệnh. Chỉ tiêu đề và đa nền tảng. Chỉ sử dụng thư viện ISO C ++ và Boost C ++. IMHO nó dễ dàng hơn Boost.Program_options.
Thư viện: http://sourceforge.net/projects/clp-parser/
Ngày 26 tháng 10 năm 2010 - bản phát hành mới 2.0rc. Nhiều lỗi đã được sửa, cấu trúc lại toàn bộ mã nguồn, tài liệu, ví dụ và nhận xét đã được sửa.
Bạn có thể thử tiêu đề tùy chọn nhỏ của tôi (166 vị trí rất dễ hack) options.hpp . Nó là một triển khai tiêu đề duy nhất và sẽ thực hiện những gì bạn yêu cầu. Nó cũng tự động in cho bạn trang trợ giúp.