如果程序被指定像这样运行,那么在c++中解析命令行参数的最佳方式是什么:
prog [-abc] [input [output]]
是否有某种方法可以在标准库中实现这一点,或者我需要自己编写代码?
相关:
在unicode c++应用程序中解析命令行参数
如果程序被指定像这样运行,那么在c++中解析命令行参数的最佳方式是什么:
prog [-abc] [input [output]]
是否有某种方法可以在标准库中实现这一点,或者我需要自己编写代码?
相关:
在unicode c++应用程序中解析命令行参数
当前回答
一个简单的解决方案是将argv放入std::map中,以便查找:
map<string, string> argvToMap(int argc, char * argv[])
{
map<string, string> args;
for(int i=1; i<argc; i++) {
if (argv[i][0] == '-') {
const string key = argv[i];
string value = "";
if (i+1 < argc && argv[i+1][0] != '-') {
value = string(argv[i+1]);
i++;
}
args[key] = value;
}
}
return args;
}
使用示例:
#include <map>
#include <string>
#include <iostream>
using namespace std;
map<string, string> argvToMap(int argc, char * argv[])
{
map<string, string> args;
for(int i=1; i<argc; i++) {
if (argv[i][0] == '-') {
const string key = argv[i];
string value = "";
if (i+1 < argc && argv[i+1][0] != '-') {
value = string(argv[i+1]);
i++;
}
args[key] = value;
}
}
return args;
}
void printUsage()
{
cout << "simple_args: A sample program for simple arg parsing\n"
"\n"
"Example usage:\n"
" ./simple_args --print-all --option 1 --flag 2\n";
}
int main(int argc, char * argv[])
{
auto args = argvToMap(argc, argv);
if (args.count("-h") || args.count("--help")) {
printUsage();
}
else if (args.count("--print-all")) {
for (auto const & pair: args)
cout << "{" << pair.first << ": " << pair.second << "}\n";
}
return 0;
}
输出:
$ ./simple_args --print-all --option 1 --flag "hello world"
{--flag: hello world}
{--option: 1}
{--print-all: }
这种方法肯定有很大的局限性,但我发现它很好地平衡了简单性和实用性。
其他回答
如果可以的话,我还建议查看一下我编写的选项解析库:drop。
它是一个C库(如果需要,还带有c++包装器)。 它是轻量级的。 它是可扩展的(自定义参数类型可以很容易地添加,并且与内置参数类型具有相同的基础)。 它应该是非常可移植的(它是用标准C编写的),没有依赖关系(除了C标准库)。 它有一个非常无限制的许可证(zlib/libpng)。
它提供了许多其他功能没有的一个功能是覆盖先前选项的能力。例如,如果你有一个shell别名:
alias bar="foo --flag1 --flag2 --flag3"
你想要使用bar但禁用了——flag1,它允许你做:
bar --flag1=0
提振。Program_options
我在windows/mingw下使用getopt():
while ((c = getopt(myargc, myargv, "vp:d:rcx")) != -1) {
switch (c) {
case 'v': // print version
printf("%s Version %s\n", myargv[0], VERSION);
exit(0);
break;
case 'p': // change local port to listen to
strncpy(g_portnum, optarg, 10);
break;
...
谷歌的旗帜
您可以使用GNU GetOpt (LGPL)或各种c++端口之一,例如getoptpp (GPL)。
一个简单的例子使用GetOpt你想要的东西(prog [-ab] input)如下:
// 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;
}