【问题标题】:Error while using getopt使用 getopt 时出错
【发布时间】:2017-09-06 10:31:55
【问题描述】:

当我传递任何参数时,我得到这个错误:分段错误(核心转储) 只有 -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 程序中使用 system Call 调用 python 脚本。

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

【问题讨论】:

  • {"algorithm",no_argument, 0,'a' } --> {"algorithm",required_argument, 0,'a' }(与se相同)和"seadh:" --> "s:e:a:d:h"
  • 等等……你真的需要“帮助”的论据,而不是反过来?
  • @BLUEPIXY "s:e:a:d:h" 这行得通,但是如何将此选项值保存到不同的变量中?我的主要要求是将其发送到在 c 程序中调用的 python 脚本的选项。在代码之后阅读问题的结尾部分,我该怎么做?
  • @BLUEPIXY {"algorithm",no_argument, 0,'a' } --> {"algorithm",required_argument, 0,'a' } , option a, s and e are optional , only -d 选项是必须的,所以我还需要将所有其他选项设为 required_argument 吗?
  • @programmer 我选择相信文档。

标签: c arguments getopt getopt-long


【解决方案1】:

getopt_long()的签名是

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

optstring 中的字符是短选项。如果短选项名称后跟冒号 (:),则该选项始终需要一个参数。与 optstring 中的空头选项 e 一样,例如 "ae:d"

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

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

因此,在您的情况下,optstring 应该是 a:d:e:s:h

optarg points to the argument of the option only if the option has one.否则将是(null)

取消引用 NULL 会调用未定义的行为。见here

您需要的短选项是ades,它们都可以带参数。我假设他们总是争论不休。如果这是您想要的,请将其更改为可选参数。

我们通过optarg 获取参数,它将指向参数字符串。如果您需要将参数作为数字,则必须将字符串转换为数字。请参阅this 帖子了解如何转换为整数。

由于您的所有选项都需要参数,因此struct optionhas_arg 字段应为required_argument 而不是no_argument。如果参数是可选的,则将其设为 `optional_argument'。

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

【讨论】:

    猜你喜欢
    • 2018-07-26
    • 2021-03-20
    • 1970-01-01
    • 1970-01-01
    • 2015-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多