我正在寻找一种使用argp为单个选项传递多个参数的方法。 我想以这种方式调用我的命令行工具:
./foo -l user1 user2 user3 -name bar
在这里,我希望将user1,user2和user3作为参数传递给-l选项。由于argp每个选项只接受1个参数,我该如何实现呢?
目前,我有以下结构:
struct arguments arguments;
arguments.lists = "";
arguments.name = "";
argparse (&argp, argc, argv, 0, 0, &arguments);
因此,在正确解析选项-l之后,argument.lists应该是“user1 user2 user3”而不是“user1”。 感谢
答案 0 :(得分:2)
命令行上的标准语法是:
./foo -l user1 -l user2 -l user3 -name bar
大多数命令行解析库都会理解这一点。
答案 1 :(得分:0)
如何在argv[]
数组中显示参数将取决于所使用的命令shell。大多数命令shell遵循普遍接受的标准,命令行参数由空格分隔,如果要指定带空格的参数,则必须引用它。
所以./foo -l user1 user2 user3 -name foo
是一个命令行,它将作为七个参数提供给C运行时,第一个是程序的名称,其余六个参数为-l
,{{1} },user1
,user2
,user3
和-name
。
如果在命令行中输入了foo
,其中用户列表(user1,user2和user3)位于带引号的字符串中,则命令行将作为五个参数提供给C运行时, first是程序的名称,其余四个参数为./foo -l "user1 user2 user3" -name foo
,-l
(引号通常由命令shell删除,所有引号都在同一个参数中),user1 user2 user3
和-name
。
回到UNIX C命令行实用程序的旧时代,我们将执行类似以下操作的简单命令行解析。以下源代码执行命令行类可能执行的工作。这是用C ++完成的,但是采用C风格。
当然,因为它被抛在一起,所以它不是很健壮,例如,特定命令行选项的超过30个参数会导致问题。
foo
// arglist.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
/*
* argument options accepted are as follows:
* -l -> indicates a user list of one or more user names follows
* -name -> indicates a name for the list follows
*
* arguments without a leading dash are considered to be option changes
* and arguments without a leading dash are considered to be arguments
* for the last option.
**/
typedef struct {
int index;
int argListIndex[30];
} argList;
const int indexOptionUnknown = 0;
const int indexOptionL = 1;
const int indexOptionName = 2;
int main(int argc, char * argv[])
{
// the index into the argv[] array. zeroth element of argve[] is ignored.
argList myList[3] = {0};
int iMyList = 0;
// we skip the first argument which is the name of our program
// we then process the remaining command line arguments which the C runtime
// has provided as a series of char strings.
for (int i = 1; i < argc; i++) {
if (*argv[i] == '-') {
// this is an argument option. figure out which one.
if (strcmp (argv[i], "-l") == 0) {
iMyList = indexOptionL;
} else if (strcmp (argv[i], "-name") == 0) {
iMyList = indexOptionName;
} else {
// unknown option so we will ignore it.
iMyList = indexOptionUnknown;
}
} else {
// this is an argument for the last option found
if (iMyList > indexOptionUnknown) {
myList[iMyList].argListIndex[ myList[iMyList].index ] = i;
myList[iMyList].index++;
}
}
}
std::cout << "option -l, count of arguments " << myList[indexOptionL].index << std::endl;
for (int i = 0; i < myList[indexOptionL].index; i++) {
std::cout << " " << i << " is " << argv[myList[indexOptionL].argListIndex[i]] << std::endl;
}
std::cout << "option -name, count of arguments " << myList[indexOptionName].index << std::endl;
for (int i = 0; i < myList[indexOptionName].index; i++) {
std::cout << " " << i << " is " << argv[myList[indexOptionName].argListIndex[i]] << std::endl;
}
return 0;
}
等参数行的输出为:
pgm -l user1 user2 user3 -name foo
option -l, count of arguments 3
0 is user1
1 is user2
2 is user3
option -name, count of arguments 1
0 is foo
之类的命令行将是相同的输出。该解析器的作用是在命令行上为特定选项构建参数列表。
如果提供了诸如pgm -l user1 -l user2 -l user3 -name foo
之类的命令行,则输出会因引用的参数而更改,结果为:
pgm -l "user1 user2 user3" -name foo
答案 2 :(得分:-1)
不确定这是否正确,但我能够按照以下方式执行此操作:
if (strlen(arguments->lists) != 0) {
char *temp;
sprintf(temp, " %s", arg);
strcat(arguments->lists, temp);
}
else {
arguments->lists = arg;
}
这样,如果为选项-l
或--lists
传递了额外的arg,则会根据需要附加它。