使用getopt时出错

时间:2017-04-11 07:13:38

标签: c arguments getopt getopt-long

当我传递任何参数时,我收到此错误:分段错误(核心转储) 只有-h选项才能正常工作。

这里选项-d和-a取字符串值 选项-s和-e取整数值。

如何保存传递给不同变量的选项值以供以后使用?

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>

void usage() {
    printf("Usage: help\n----------\n------");
}

int main(int argc, char *argv[]) {
    int opt= 0;
    int start = -1, end = -1;
    char *alg,*dir;

    static struct option long_options[] = {
        {"start",no_argument,0,'s' },
        {"end",no_argument,0,'e' },
        {"algorithm",no_argument, 0,'a' },
        {"directory",required_argument, 0,'d' },
        {0,0,0,0}
    };

    int long_index =0;
    while ((opt = getopt_long(argc, argv,"seadh:",
               long_options, &long_index )) != -1) {
        switch (opt) {
          case 'a' :
            printf("you entered \"%s\"\n", optarg); // error while printing this
            break;
          case 'd' :
            printf("you entered \"%s\"\n", optarg);
            break;
          case 's' : start = atoi(optarg);
            break;
          case 'e' : end = atoi(optarg);
            break;
          case 'h' : usage();
            break;
          default: usage();
            exit(EXIT_FAILURE);
        }
    }
    printf("%d",start);

    return 0;
}

我想使用与其值一起传递的选项,使用系统调用在此C程序中调用python脚本。

例如:system(python alg.py -alr -s3 -e45 -d / path)

1 个答案:

答案 0 :(得分:0)

getopt_long()的签名是

int getopt_long(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex);

optstring中的字符是短选项。如果短选项名称后跟冒号(:),则该选项始终需要参数。与eoptstring之类的"ae:d"短选项y的情况一样。

如果"ae:y::f"中的optstring有两个冒号,则短选项的参数是可选的。

如果optstring中的短选项字符后没有冒号,则表示该选项永远不会参数。

因此,在您的情况下,a:d:e:s:h应为optarg

仅当选项有一个时,

(null)才指向选项的参数。否则它将是NULL

取消引用a会调用未定义的行为。请参阅here

您需要的简短选项包括desoptarg,所有这些选项都可以参与。我假设他们总是在争吵。如果这是你想要的,那就把它改成可选参数。

我们通过has_arg获取参数,该参数将指向参数字符串。如果您需要将参数作为数字,则必须将字符串转换为数字。有关转换为整数的信息,请参阅this帖子。

由于您的所有选项都需要参数,struct option的{​​{1}}字段应为required_argument而不是no_argument。如果参数是可选的,请将其设为`optional_argument&#39;。

static struct option long_options[] = {
    {"start", required_argument,0,'s' },
    {"end", required_argument,0,'e' },
    {"algorithm", required_argument, 0,'a' },
    {"directory",required_argument, 0,'d' },
};

所以循环可能就像

int c, longindex=0, n;
while( (c=getopt_long(argc, argv, "a:e:d:s:h", long_options, &longindex ))!=-1 )
{
    switch(c)
    {
    case 'a':
        fprintf(stdout, "\na value: %s", optarg);
        break;
    case 'e':
        n=strtol(optarg, NULL, 10);
        fprintf(stdout, "\ne value: %d", n);
        break;
    case 'd':
        fprintf(stdout, "\nd value: %s", optarg);
        break;
    case 's':
        n=strtol(optarg, NULL, 10);
        fprintf(stdout, "\ns value: %d", n);
        break;
    case 'h':
        printf("\nh found.");
        break;
    }
}

为简洁起见,我没有在strtol()之后完成错误检查,你应该处理它。

你应该处理诸如未知标志,重复标志,额外参数等问题。检查getopt的man page