在使用 getopt 时出现“分段错误 - 核心已转储”错误。

3

我知道这个问题已经被多次提出,但我仍然无法弄清楚这个问题

#include<stdio.h>
#include<getopt.h>
int ch;
int queue_time=60;
int thread_num=4;
char *scheduling_algo="FCFS";
extern char *optarg;
int port=8080;
int debug_flag,h_flag,l_flag;
int main(int argc,char *argv[])
{
  while ((ch = getopt(argc, argv, "dhlprtns")) != -1)
switch(ch)
{
  case 'd':
    debug_flag=atoi(optarg);        /* print address in output */
    break;
  case 'h':
    h_flag=atoi(optarg);
    break;
  case 'l':
    l_flag=atoi(optarg);; 
    break;
  case 'p':
    port = atoi(optarg);
    break;
case 'r':
    printf("%s",optarg); 
    break;
case 't':
    queue_time = atoi(optarg);
    break;
case 'n':
    thread_num = atoi(optarg);
    break;
case 's':
    scheduling_algo = optarg;
    break;
default:
    printf("nothing was passed");
}

    printf("%d",queue_time);
    printf("%d",debug_flag);
    printf("%d",h_flag);
    printf("%d",l_flag);
}   

我正在使用以下命令执行我的程序

./a.out -d -h -l -t 55

我遇到了核心转储错误。我在谷歌上读了几个例子,但仍然面临这个问题。有人可以帮忙吗?

2个回答

15

你需要阅读getopt()函数的man手册。

  while ((ch = getopt(argc, argv, "dhlprtns")) != -1)
                                   ^^^^^^^^

这不符合您使用参数的方式。您需要在期望参数的标志后面加上冒号“:”。在您的代码中,“d”后面没有加冒号,但您似乎还想获取其值:

  case 'd':
    debug_flag=atoi(optarg);        /* print address in output */
    break;

发生的情况是你在调用 atoi(0),这导致了段错误。

以下是man手册中的示例,请注意,“b”后面没有冒号而“f”有。

#include <unistd.h>
 int bflag, ch, fd;

 bflag = 0;
 while ((ch = getopt(argc, argv, "bf:")) != -1) {
         switch (ch) {
         case 'b':
                 bflag = 1;
                 break;
         case 'f':
                 if ((fd = open(optarg, O_RDONLY, 0)) < 0) {
                         (void)fprintf(stderr,
                             "myname: %s: %s\n", optarg, strerror(errno));
                         exit(1);
                 }
                 break;
         case '?':
         default:
                 usage();
         }
 }
 argc -= optind;
 argv += optind;

非常感谢,手册真的很令人困惑。现在我有了清晰的认识。我只需要针对那些带有冒号的标志使用optarg。 - user2934433

1
这可能对其他人有用:如果您在选项字母上同时指定了带冒号和不带冒号的选项,例如“dabcd:e”,则也会导致段错误...然后使用该选项字母。看起来 getopt 及其变体不检查此冲突并返回错误!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接