【问题标题】:Using getopt() and switch statements in C在 C 中使用 getopt() 和 switch 语句
【发布时间】:2015-03-04 19:41:34
【问题描述】:

我是 C 新手,并尝试将 getopt 与 switch 语句结合使用。我认为我的问题只是语法问题,但我似乎无法弄清楚。我需要像这样运行我的程序: $/webserver -p 8080 -r /my/root/dir。 所以我需要识别 -p 并获取 8080 并识别 -r 并获取 /my/root/dir。目前我的代码找到 -p 然后找到 -r 然后检测到未知选项并退出。这是代码。我有puts() 在那里进行测试。

   #define USAGE_STRING "Usage: webserver -p <port> -r  <rootdir>\n"
char *port;
char *rootdir;
// Process command line arguments. Uses GNU getopt() function.
void processargs(int argc, char **argv) {
  int next_option;
  do {
    next_option = getopt(argc, argv, "pr:");
    if (next_option != -1) {
      switch (next_option)
      {
        case 'p': /* -p -- port option  */
          puts("p");

          port = optarg;
         printf("%s", port);
        case 'r': // -r -- root directory option
          puts("r");
          rootdir = optarg;  
        printf("%s", rootdir);
        default:
             puts("unknown");
          /* Unknown option detected. Print it to standard
                output, and exit with exit code zero (normal termination). */
          fprintf(stderr, USAGE_STRING);
          exit(1);

      }
    }
  } while (next_option != -1);
  printf("%s", port);

  if (port == NULL) {

          fprintf(stderr, USAGE_STRING);
          exit(1);
    }
  if (rootdir == NULL) {
  puts("unknown");
          fprintf(stderr, USAGE_STRING);
          exit(1);
    }


}

目前,当我运行上述命令时,我得到了这个输出(使用 puts 进行测试)。

p
r
unknown
Usage: webserver -p <port> -r  <rootdir>

感谢您的帮助!

【问题讨论】:

  • 您的switch 语句缺少每个case 末尾的break
  • 另外,你的选项字符串应该是"p:r:",而不是"pr:"

标签: c switch-statement arguments getopt


【解决方案1】:

我相信您想在每个案例结束时使用break,否则执行会进入下一个案例块。

【讨论】:

  • @irrrgg 我包括了中断,并将选项字符串更改为p:r,但它仍然无法识别rootdir。我错过了什么吗?
【解决方案2】:

C switch 语句需要在每个 case 的末尾加上 break,否则会执行以下 case 中的代码。所以这个:

switch (next_option)
{
case 'p':                      /* -p -- port option */
    puts("p");

    port = optarg;
    printf("%s", port);
case 'r':                      // -r -- root directory option
    puts("r");
    rootdir = optarg;
    printf("%s", rootdir);
default:
    puts("unknown");
    /* Unknown option detected. Print it to standard output, and exit with exit code zero
       (normal termination). */
    fprintf(stderr, USAGE_STRING);
    exit(1);
}

必须改成这样:

switch (next_option)
{
case 'p':                      /* -p -- port option */
    puts("p");

    port = optarg;
    printf("%s", port);
    break;
case 'r':                      // -r -- root directory option
    puts("r");
    rootdir = optarg;
    printf("%s", rootdir);
    break;
default:
    puts("unknown");
    /* Unknown option detected. Print it to standard output, and exit with exit code zero
       (normal termination). */
    fprintf(stderr, USAGE_STRING);
    exit(1);
}

【讨论】:

    【解决方案3】:

    首先你应该使用getopt_long() 我相信getopt() 已经被贬值了。您的 switch 语句中也缺少break。如果没有中断,则该情况下的每个案例都将被执行。虽然您可以使用 do-while 循环,但仅使用 while 循环会更简单。

    这是一个可以构建的简单命令行解析器。

    static const char *optstring = "p:r:";
    
    static struct option longopts[] =
    {
        { "port", required_argument, NULL, 'p' },
        { "root", required_argument, NULL, 'r' },
        { NULL, 0, NULL, 0 }
    };
    
    int parseInput(int argc, char * const argv[])
    {
        int ch;
    
        /* Main Loop ie the Parser */
        while ((ch = getopt_long(argc, argv, optstring, longopts, NULL)) != -1)
        {
            switch(ch)
            {
                case 'p':
                    printf("arg: %s\n", optarg);
                    break;
    
                case 'r':
                    printf("arg: %s\n", optarg);
                    break;
    
                default:
                    printf("Unsupported option\n");
                    return -1;
            }
       }
       return 0;
    }
    

    【讨论】:

    • 这会在结构初始化中为 eacher { 引发此错误。警告:initialization makes pointer from integer without a cast [enabled by default] { "port", 0, required_argument, 'p' }, ^
    • 对不起,我试图凭记忆写它并犯了一些愚蠢的错误,但现在试试吧。
    猜你喜欢
    • 2022-06-19
    • 2012-04-14
    • 2012-10-01
    • 1970-01-01
    • 2017-12-13
    • 1970-01-01
    • 1970-01-01
    • 2012-10-25
    • 1970-01-01
    相关资源
    最近更新 更多