【问题标题】:Getopt- Passing string parameter for argumentGetopt-为参数传递字符串参数
【发布时间】:2013-07-26 11:43:05
【问题描述】:

我有一个接受多个命令行参数的程序,所以我使用 getopt。我的一个论点接受一个字符串作为参数。无论如何要通过 getopt 函数获取该字符串,还是必须通过 argv[] 数组获取它? getopt 也可以读取像 -file 这样的参数吗?到目前为止我看到的所有论点都只有一个字符,例如-a

编辑

根据下面的答案,我编写了一个使用 getopt_long() 的程序,但 switch 语句仅在我使用字符参数而不是长参数时识别参数。我不确定为什么会这样。在传递参数-mf -file sample 时,我没有看到打印语句。

编辑

我尝试将命令参数输入为--file,然后它起作用了。仅使用-file 就不可能做到这一点吗?

static struct option long_options[] =
{
    {"mf", required_argument, NULL, 'a'},
    {"md", required_argument, NULL, 'b'},
    {"mn", required_argument, NULL, 'c'},
    {"mw", required_argument, NULL, 'd'},
    {"lf", required_argument, NULL, 'e'},
    {"ld", required_argument, NULL, 'f'},
    {"ln", required_argument, NULL, 'g'},
    {"lw", required_argument, NULL, 'h'},
    {"rf", required_argument, NULL, 'i'},
    {"rd", required_argument, NULL, 'j'},
    {"rn", required_argument, NULL, 'k'},
    {"rw", required_argument, NULL, 'l'},
    {"df", required_argument, NULL, 'm'},
    {"dd", required_argument, NULL, 'n'},
    {"dn", required_argument, NULL, 'o'},
    {"dw", required_argument, NULL, 'p'},
    {"file", required_argument, NULL, 'q'},
    {NULL, 0, NULL, 0}
};
int ch=0;
while ((ch = getopt_long(argc, argv, "abcdefghijklmnopq:", long_options, NULL)) != -1)
{
    // check to see if a single character or long option came through
        switch (ch){
        case 'a':
            cout<<"title";
            break;
        case 'b':
            
            break;
        case 'c':
            
            break;
        case 'd':
            
            break;
        case 'e':
            
            break;
        case 'f':
            
            break;
        case 'g':
            
            break;
        case 'h':
            
            break;
        case 'i':
            
            break;
        case 'j':
            
            break;
        case 'k':
            
            break;
        case 'l':
            
            break;
        case 'm':
            
            break;
        case 'n':
            
            break;
        case 'o':
            
            break;
        case 'p':
            
            break;
        case 'q':
            cout<<"file";
            break;
        case '?':
            cout<<"wrong message"
            break;  
    }
}

【问题讨论】:

    标签: c getopt


    【解决方案1】:

    阅读man getopthttp://linux.die.net/man/3/getopt

    optstring 是一个包含合法选项字符的字符串。如果 这样的字符后跟一个冒号,该选项需要一个 参数,因此 getopt() 在 相同的 argv 元素,或以下 argv 元素的文本,在 选择参数。两个冒号表示一个选项带有一个可选参数;如果有 当前 argv 元素中的文本(即,与选项在同一个词中 名称本身,例如“-oarg”),然后在 optarg 中返回, 否则 optarg 设置为零。

    示例代码:

    #include <stdio.h>
    #include <unistd.h>
    
    int main (int argc, char *argv[])
    {
      int opt;
      while ((opt = getopt (argc, argv, "i:o:")) != -1)
      {
        switch (opt)
        {
          case 'i':
                    printf("Input file: \"%s\"\n", optarg);
                    break;
          case 'o':
                    printf("Output file: \"%s\"\n", optarg);
                    break;
        }
      }
      return 0;
    }
    

    这里的optstring 是“i:o:”,字符串中每个字符后面的冒号“:”表示这些选项需要一个参数。您可以在 optarg 全局变量中找到作为字符串的参数。有关详细信息和更多示例,请参阅手册。

    对于多个字符的选项开关,请参阅长选项getopt_long。查看手册以获取示例。

    EDIT 响应单个 '-' 长选项:

    来自手册页

    getopt_long_only() 类似于 getopt_long(),但 '-' 和 "--" 可以表示一个长选项。如果以“-”开头的选项 (not "--") 不匹配长选项,但匹配短选项, 它被解析为一个短选项。

    查看手册并尝试一下。

    【讨论】:

    • 我曾尝试使用 getopt_long,但我的程序无法识别参数。我已经在上面添加了我的代码。
    【解决方案2】:

    要指定一个标志需要一个参数,请在 short_opt 变量中的标志之后添加一个“:”。要使用长参数,请使用 getopt_long()。

    这是一个简单的示例程序:

    #include <getopt.h>
    #include <stdio.h>
    
    int main(int argc, char * argv[]);
    
    int main(int argc, char * argv[])
    {
       int             c;
       const char    * short_opt = "hf:";
       struct option   long_opt[] =
       {
          {"help",          no_argument,       NULL, 'h'},
          {"file",          required_argument, NULL, 'f'},
          {NULL,            0,                 NULL, 0  }
       };
    
       while((c = getopt_long(argc, argv, short_opt, long_opt, NULL)) != -1)
       {
          switch(c)
          {
             case -1:       /* no more arguments */
             case 0:        /* long options toggles */
             break;
    
             case 'f':
             printf("you entered \"%s\"\n", optarg);
             break;
    
             case 'h':
             printf("Usage: %s [OPTIONS]\n", argv[0]);
             printf("  -f file                   file\n");
             printf("  -h, --help                print this help and exit\n");
             printf("\n");
             return(0);
    
             case ':':
             case '?':
             fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]);
             return(-2);
    
             default:
             fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c);
             fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]);
             return(-2);
          };
       };
    
       return(0);
    }
    

    【讨论】:

    • 我可以用于 getopt_long() 的不同参数的数量是否有限制?我有 17 个不同的参数,它只在我输入参数的字符版本而不是长参数时识别参数。
    • 相信你只是受记忆的限制。您是否更新了 long_opts 的最后一个值?在我的示例中,每个长选项都与一个短选项配对。所以 '--help' 和 '-h' 是同一个选项。但是,您可以通过将“h”更改为“p”并将“p”添加到 short_opt 字符串来使“--help”与“-p”选项相同。
    • 我刚刚读到你的编辑。您必须使用“--option”而不是“-option”。 getopt() 和 getopt_long() 会将“-option”解释为“-o -p -t -i -o -n”。如果您想使用带有单个破折号的长选项,则必须编写自己的 CLI 参数解析器,或者尝试找到与您所需行为匹配的现有解析器。
    猜你喜欢
    • 1970-01-01
    • 2018-08-05
    • 1970-01-01
    • 1970-01-01
    • 2014-08-25
    • 1970-01-01
    • 1970-01-01
    • 2017-06-14
    相关资源
    最近更新 更多