是否可以将argp配置为将-1,-4,-99等解释为负数参数而不是开关?我的C程序目前只允许一个开关(-v)。如果我将程序-4作为命令行参数传递,则argp会显示错误消息
无效选项 - ' 4'
示例代码:
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <argp.h>
static const char *argpErrors[] = { "OK.", \
/* 01 */ "Too few arguments provided", \
/* 02 */ "Too many argument provided", \
/* 03 */ "Argument 1 must be an integer.", \
/* 04 */ "Argument 2 must be an integer.", \
/* 05 */ "Argument 3 must be an integer.", \
/* 06 */ "Unable to parse command line arguments." };
static struct argp_option options[] = {
// name, key, argname, flags, doc, group
{"verbose", 'v', 0, 0, "Produce verbose output"},
{ 0 }
};
struct arguments
{
int argCount;
bool verbose;
int num[3];
};
bool isInteger(char *str)
{
bool digitFound = false;
int i;
int chars = (int)strlen((const char *)str);
for (i = 0; i < chars; ++i)
{
if ((i == 0) && (str[0] == '-'))
{
continue;
}
if (isdigit(str[i]))
{
digitFound = true;
continue;
}
return false;
}
return digitFound;
}
void reportArgpError(bool verbose, struct argp_state *state, int errorNumber)
{
if (verbose)
{
argp_failure(state, 1, 0, argpErrors[errorNumber]);
}
else
{
printf("%d\n", errorNumber);
exit(-1);
}
}
static error_t parse_opt(int key, char *arg, struct argp_state *state)
{
struct arguments *arguments = state->input;
switch (key)
{
case 'v':
arguments->verbose = true;
break;
case ARGP_KEY_NO_ARGS:
reportArgpError(arguments->verbose, state, 1);
break;
case ARGP_KEY_ARG:
arguments->argCount++;
if (arguments->argCount > 3)
{
reportArgpError(arguments->verbose, state, 2);
}
else
{
if (isInteger(arg))
{
arguments->num[arguments->argCount - 1] = atoi(arg);
}
else
{
reportArgpError(arguments->verbose, state, 2 + arguments->argCount);
}
}
break;
case ARGP_KEY_END:
if (arguments->argCount < 3)
{
reportArgpError(arguments->verbose, state, 1);
}
else if (arguments->argCount > 3)
{
reportArgpError(arguments->verbose, state, 2);
}
break;
default:
break;
}
return 0;
}
static char args_doc[] = "num1 num2 num3";
static char doc[] = "Example for StackOverflow";
static struct argp argp = { options, parse_opt, args_doc, doc };
int main(int argc, char *argv[])
{
struct arguments arguments;
arguments.argCount = 0;
arguments.verbose = false;
argp_parse (&argp, argc, argv, 0, 0, &arguments);
if (arguments.verbose)
{
puts("Success");
printf("num1 = %d\n", arguments.num[0]);
printf("num2 = %d\n", arguments.num[1]);
printf("num3 = %d\n", arguments.num[2]);
}
else
{
printf("0 %d %d %d\n", arguments.num[0], arguments.num[1], arguments.num[2]);
}
return 0;
}
示例命令:
./a.out -v 33 66 99
响应:
Success
num1 = 33
num2 = 66
num3 = 99
示例命令:
./a.out -v 33 -4 9
响应:
./a.out: invalid option -- '4'
Try `a.out --help' or `a.out --usage' for more information.
答案 0 :(得分:1)
./a.out -v -- 33 -4 9
工作了。谢谢nwellnhof。
更换&#39; - &#39;带有&#39; n&#39;的字符在调用argp_parse()并更改&#39; n&#39;之前回到&#39; - &#39;在ARGP_KEY_ARG切换键块中也有效。源代码如下:
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <argp.h>
static const char *argpErrors[] = { "OK.", \
/* 01 */ "Too few arguments provided", \
/* 02 */ "Too many argument provided", \
/* 03 */ "Argument 1 must be an integer.", \
/* 04 */ "Argument 2 must be an integer.", \
/* 05 */ "Argument 3 must be an integer.", \
/* 06 */ "Unable to parse command line arguments." };
static struct argp_option options[] = {
// name, key, argname, flags, doc, group
{"verbose", 'v', 0, 0, "Produce verbose output"},
{ 0 }
};
struct arguments
{
int argCount;
bool verbose;
int num[3];
};
bool isInteger(char *str)
{
bool digitFound = false;
int i;
int chars = (int)strlen((const char *)str);
for (i = 0; i < chars; ++i)
{
if ((i == 0) && (str[0] == '-'))
{
continue;
}
if (isdigit(str[i]))
{
digitFound = true;
continue;
}
return false;
}
return digitFound;
}
void reportArgpError(bool verbose, struct argp_state *state, int errorNumber)
{
if (verbose)
{
argp_failure(state, 1, 0, argpErrors[errorNumber]);
}
else
{
printf("%d\n", errorNumber);
exit(-1);
}
}
void replaceIntegerPrefixChar(char *str, char originalChar, char newChar)
{
int len = (int)strlen(str);
if (len > 1)
{
if ((str[0] == originalChar) && (isInteger(str + 1)))
{
str[0] = newChar;
}
}
return;
}
static error_t parse_opt(int key, char *arg, struct argp_state *state)
{
struct arguments *arguments = state->input;
switch (key)
{
case 'v':
arguments->verbose = true;
break;
case ARGP_KEY_NO_ARGS:
reportArgpError(arguments->verbose, state, 1);
break;
case ARGP_KEY_ARG:
arguments->argCount++;
if (arguments->argCount > 3)
{
reportArgpError(arguments->verbose, state, 2);
}
else
{
replaceIntegerPrefixChar(arg, 'n', '-');
if (isInteger(arg))
{
arguments->num[arguments->argCount - 1] = atoi(arg);
}
else
{
reportArgpError(arguments->verbose, state, 2 + arguments->argCount);
}
}
break;
case ARGP_KEY_END:
if (arguments->argCount < 3)
{
reportArgpError(arguments->verbose, state, 1);
}
else if (arguments->argCount > 3)
{
reportArgpError(arguments->verbose, state, 2);
}
break;
default:
//reportArgpError(arguments->verbose, state, false, 13);
break;
}
return 0;
}
static char args_doc[] = "num1 num2 num3";
static char doc[] = "Example for StackOverflow";
static struct argp argp = { options, parse_opt, args_doc, doc };
int main(int argc, char *argv[])
{
struct arguments arguments;
arguments.argCount = 0;
arguments.verbose = false;
int i;
for (i = 0; i < argc; ++i)
{
replaceIntegerPrefixChar(argv[i], '-', 'n');
}
argp_parse (&argp, argc, argv, 0, 0, &arguments);
if (arguments.verbose)
{
puts("Success");
printf("num1 = %d\n", arguments.num[0]);
printf("num2 = %d\n", arguments.num[1]);
printf("num3 = %d\n", arguments.num[2]);
}
else
{
printf("0 %d %d %d\n", arguments.num[0], arguments.num[1], arguments.num[2]);
}
return 0;
}