【问题标题】:C getopt multiple valueC getopt 多值
【发布时间】:2011-04-25 17:55:09
【问题描述】:

我的论点是这样的

./a.out -i file1 file2 file3

如何利用getopt() 获取3 个(或更多)输入文件? 我正在做这样的事情:

while ((opt = getopt(argc, argv, "i:xyz.."))!= -1){
  case 'i':
     input = optarg; 
     break;
  ...
}

我只得到file1;如何获得file2、file3?

【问题讨论】:

  • 请注意,Supplying two arguments to command line option using getopt() 问题提供了一些此处未提及的可能性。
  • 在程序代码中调整optind 下面的答案如履薄冰。如果您在调用代码中修改optind 或optarg,则没有记录要求getopt() 的行为。当然,大多数当前和合理的实现不会有问题,但是假设的实现可以在非全局变量中记录其内部状态,并在返回时简单地设置全局变量。这样的实现将满足getopt() 的 POSIX 规范,但显示的修补不起作用。

标签: c input getopt


【解决方案1】:

我知道这已经很老了,但我在寻找解决方案时遇到了这个问题。

while((command = getopt(argc, argv, "a:")) != -1){

    switch(command){
        case 'a':

        (...)

        optind--;
        for( ;optind < argc && *argv[optind] != '-'; optind++){
              DoSomething( argv[optind] );         
        }

        break;
    }

我发现 int optind (由 getopt() 使用的外部)指向由 argv”之后的下一个位置em>getopt(); 这就是为什么我一开始就减少它的原因。

首先 for 循环 检查当前参数的值是否在 argv 的边界内(argc 是数组的长度,所以最后数组 argv 中的位置是 argc-1)。 && 的第二部分比较下一个参数的第一个字符是否为“-”。如果第一个字符是 '-' 那么我们用完了当前参数的下一个值,否则 argv[optind] 是我们的下一个值。以此类推,直到 argv 结束或参数用完值。

最后增加 optind 以检查下一个 argv。

请注意,因为我们正在检查 'optind ',除非第一部分为真,否则不会执行条件的第二部分,因此不必担心读取数组边界之外的内容。

PS 我是一个相当新的 C 程序员,如果有人有改进或批评,请分享。

【讨论】:

  • 这已经很老了,但我想我可以添加一个评论。您不仅应该检查“-”,还应该确保strlen(argv[optind]) 等于 2。这将确保它将正确处理以破折号开头的参数。这段代码对我很有帮助! +1
【解决方案2】:

如果必须,您可以从 argv[optind] 开始并自己增加 optind。但是,我建议不要这样做,因为我认为这种语法形式很差。 (你怎么知道你何时到达列表的末尾?如果有人有一个以- 作为第一个字符命名的文件怎么办?)

我认为最好将您的语法更改为:

/a.out -i file1 -i file2 -i file3

或将文件列表视为位置参数:

/a.out file1 file2 file3

【讨论】:

  • 谢谢 jamesdlin 我会看看 [optind] 因为除了 -i 之外我还有很多参数
【解决方案3】:

请注意,glibc 的不一致参数置换扩展将破坏以这种方式使用多个参数到 -i 的任何尝试。在非 GNU 系统上,“-i 的第二个参数”将被解释为第一个非选项参数,停止任何进一步的选项解析。考虑到这些问题,如果你想使用这种语法,我会放弃 getopt 并编写你自己的命令行解析器,因为它不是 getopt 支持的语法。

【讨论】:

    【解决方案4】:

    我查看并尝试了上面的代码,但我发现我的解决方案更简单一些,对我来说效果更好:

    我想要的处理是:

    -m mux_i2c_group mux_i2c_out
    

    (需要 2 个参数)。

    这就是我的结果:

    case 'm':
        mux_i2c_group = strtol(optarg, &ch_p, 0);
    
        if (optind < argc && *argv[optind] != '-'){
            mux_i2c_out = strtol(argv[optind], NULL, 0);
            optind++;
        } else {
            fprintf(stderr, "\n-m option require TWO arguments <mux_group> "
                            "<mux_out>\n\n");
            usage();
        }
    
        use_mux_flag = 1;
        break;
    

    这会像往常一样从我那里获取第一个值,然后只寻找第二个 REQUIRED 值。

    【讨论】:

    • 不错的决定!谢谢!:)
    【解决方案5】:

    事实证明,GoTTimw 的解决方案对我非常有用。但是,我想再提一个想法,这里还没有建议。

    以这种方式将参数作为一个字符串传递。

    ./a.out -i "file1 file2 file3"
    

    然后你得到一个字符串作为单个参数,你只需要用空格分割它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多