Ver*_*gen 183 c++ command-line arguments
可能重复:
C++有哪些参数解析器库?
如果指定程序运行如下,那么在C++中解析命令行参数的最佳方法是什么:
prog [-abc] [input [output]]
Run Code Online (Sandbox Code Playgroud)
STL中有一个库可以做到这一点吗?
有关:
iai*_*ain 233
对boost::program_options
GNU getopt 的建议很好.
但是,对于简单的命令行选项,我倾向于使用std :: find
例如,在-f
命令行参数后读取文件的名称.您还可以检测是否已传入单字选项,以-h
获取帮助.
#include <algorithm>
char* getCmdOption(char ** begin, char ** end, const std::string & option)
{
char ** itr = std::find(begin, end, option);
if (itr != end && ++itr != end)
{
return *itr;
}
return 0;
}
bool cmdOptionExists(char** begin, char** end, const std::string& option)
{
return std::find(begin, end, option) != end;
}
int main(int argc, char * argv[])
{
if(cmdOptionExists(argv, argv+argc, "-h"))
{
// Do stuff
}
char * filename = getCmdOption(argv, argv + argc, "-f");
if (filename)
{
// Do interesting things
// ...
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在使用这种方法要注意的事项上,必须使用std :: strings作为std :: find的值,否则将对指针值执行相等性检查.
我希望可以编辑此响应而不是添加新响应,因为这是基于原始答案.我稍微重写了函数并将它们封装在一个类中,所以这里是代码.我认为以这种方式使用也是可行的:
class InputParser{
public:
InputParser (int &argc, char **argv){
for (int i=1; i < argc; ++i)
this->tokens.push_back(std::string(argv[i]));
}
/// @author iain
const std::string& getCmdOption(const std::string &option) const{
std::vector<std::string>::const_iterator itr;
itr = std::find(this->tokens.begin(), this->tokens.end(), option);
if (itr != this->tokens.end() && ++itr != this->tokens.end()){
return *itr;
}
static const std::string empty_string("");
return empty_string;
}
/// @author iain
bool cmdOptionExists(const std::string &option) const{
return std::find(this->tokens.begin(), this->tokens.end(), option)
!= this->tokens.end();
}
private:
std::vector <std::string> tokens;
};
int main(int argc, char **argv){
InputParser input(argc, argv);
if(input.cmdOptionExists("-h")){
// Do stuff
}
const std::string &filename = input.getCmdOption("-f");
if (!filename.empty()){
// Do interesting things ...
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
小智 84
Boost.Program_options 应该可以解决问题
nau*_*ghi 58
我可以建议Templatized C++ Command Line Parser Library(GitHub上的一些分支可用),API非常简单并且(从网站引用):
该库完全在头文件中实现,使其易于使用和与其他软件一起分发.它根据MIT许可证进行许可,以实现无忧分发.
这是手册中的一个示例,为简单起见,此处着色:
#include <string>
#include <iostream>
#include <algorithm>
#include <tclap/CmdLine.h>
int main(int argc, char** argv)
{
// Wrap everything in a try block. Do this every time,
// because exceptions will be thrown for problems.
try {
// Define the command line object, and insert a message
// that describes the program. The "Command description message"
// is printed last in the help text. The second argument is the
// delimiter (usually space) and the last one is the version number.
// The CmdLine object parses the argv array based on the Arg objects
// that it contains.
TCLAP::CmdLine cmd("Command description message", ' ', "0.9");
// Define a value argument and add it to the command line.
// A value arg defines a flag and a type of value that it expects,
// such as "-n Bishop".
TCLAP::ValueArg<std::string> nameArg("n","name","Name to print",true,"homer","string");
// Add the argument nameArg to the CmdLine object. The CmdLine object
// uses this Arg to parse the command line.
cmd.add( nameArg );
// Define a switch and add it to the command line.
// A switch arg is a boolean argument and only defines a flag that
// indicates true or false. In this example the SwitchArg adds itself
// to the CmdLine object as part of the constructor. This eliminates
// the need to call the cmd.add() method. All args have support in
// their constructors to add themselves directly to the CmdLine object.
// It doesn't matter which idiom you choose, they accomplish the same thing.
TCLAP::SwitchArg reverseSwitch("r","reverse","Print name backwards", cmd, false);
// Parse the argv array.
cmd.parse( argc, argv );
// Get the value parsed by each arg.
std::string name = nameArg.getValue();
bool reverseName = reverseSwitch.getValue();
// Do what you intend.
if ( reverseName )
{
std::reverse(name.begin(),name.end());
std::cout << "My name (spelled backwards) is: " << name << std::endl;
}
else
std::cout << "My name is: " << name << std::endl;
} catch (TCLAP::ArgException &e) // catch any exceptions
{ std::cerr << "error: " << e.error() << " for arg " << e.argId() << std::endl; }
}
Run Code Online (Sandbox Code Playgroud)
Mat*_*hen 33
您可以使用GNU GetOpt(LGPL)或各种C++端口之一,例如getoptpp(GPL).
使用GetOpt的简单示例(prog [-ab]输入)如下:
// C Libraries:
#include <string>
#include <iostream>
#include <unistd.h>
// Namespaces:
using namespace std;
int main(int argc, char** argv) {
int opt;
string input = "";
bool flagA = false;
bool flagB = false;
// Retrieve the (non-option) argument:
if ( (argc <= 1) || (argv[argc-1] == NULL) || (argv[argc-1][0] == '-') ) { // there is NO input...
cerr << "No argument provided!" << endl;
//return 1;
}
else { // there is an input...
input = argv[argc-1];
}
// Debug:
cout << "input = " << input << endl;
// 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;
}
Run Code Online (Sandbox Code Playgroud)
小智 22
另一个替代方案是精益平均C++选项解析器:
http://optionparser.sourceforge.net
它是一个仅限标头的库(事实上只是一个头文件),与其他所有建议不同,它也是独立的,即它没有任何依赖性.特别是对STL没有依赖性.它甚至不使用需要库支持的异常或其他任何东西.这意味着它可以与普通的C或其他语言链接而不引入"外国"库.
像boost :: program_options一样,它的API提供了方便的直接访问选项,即你可以编写这样的代码
if(选项[HELP])...;
和
int verbosity = options [VERBOSE] .count();
与boost :: program_options不同,这只是使用一个用(用户提供的)枚举索引的数组.这提供了没有重量的关联容器的便利性.
它有详细记录,并拥有公司友好许可证(MIT).
TLMC++ OP包含一个很好的格式化用户消息,可以进行换行和列对齐,这对于本地化程序非常有用,因为它确保即使在具有较长消息的语言中输出也会很好.它还可以节省您手动格式化80列使用情况的麻烦.
小智 14
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i],"-i")==0) {
filename = argv[i+1];
printf("filename: %s",filename);
} else if (strcmp(argv[i],"-c")==0) {
convergence = atoi(argv[i + 1]);
printf("\nconvergence: %d",convergence);
} else if (strcmp(argv[i],"-a")==0) {
accuracy = atoi(argv[i + 1]);
printf("\naccuracy:%d",accuracy);
} else if (strcmp(argv[i],"-t")==0) {
targetBitRate = atof(argv[i + 1]);
printf("\ntargetBitRate:%f",targetBitRate);
} else if (strcmp(argv[i],"-f")==0) {
frameRate = atoi(argv[i + 1]);
printf("\nframeRate:%d",frameRate);
}
}
Run Code Online (Sandbox Code Playgroud)
Qt 5.2 带有一个命令行解析器 API。
小例子:
#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;
}
Run Code Online (Sandbox Code Playgroud)
自动生成的帮助屏幕:
$ ./qtopt -h 用法:./qtopt [options] infile 做 X 的工具。 选项: -h, --help 显示此帮助。 -v, --version 显示版本信息。 -+ 冗长 -o, --output 输出文件。 参数: infile 输入文件。
自动生成的版本输出:
$ ./qtopt -v 工具X 1.2
一些真实的电话:
$ ./qtopt b1 -+ -o tmp blah.foo 输入文件: ("b1", "blah.foo") ,详细: true ,输出: "tmp" $ ./qtopt 输入文件: () ,详细: false ,输出: "out"
解析错误:
$ ./qtopt --hlp 未知选项 'hlp'。 $回声 $? 1
如果您的程序已经使用 Qt (>= 5.2) 库,那么它的命令行解析 API 足够方便,可以完成工作。
请注意,内置 Qt 选项QApplication
在选项解析器运行之前被消耗。
归档时间: |
|
查看次数: |
263956 次 |
最近记录: |