首页 > 解决方案 > 在 C 中使用 getopt() 进行可变长度参数解析

问题描述

我正在尝试在 C 中实现一个多层感知器库,我想使用标志 -H 从命令行设置隐藏层的数量和每层中的感知器数量,其中第一个数字是隐藏层的数量和以下接下来的 2 个数字分别是这 2 层中的神经元数量,我正在使用 getopt() 例如,如果我想创建一个具有 2 个隐藏层的网络,每个隐藏层有 5 个神经元,我将输入:-H 2 5 5 for 3分别具有 5、4 和 3 个神经元的层我将通过 -H 3 5 4 3

while ((opt = getopt(argc, argv, ":d:i:o:h:")) != -1) {
  switch (opt) {
  case 'd':
    printf("dataset file: %s\n", optarg);
    break;
  case 'i':
    printf("number of inputs: %s\n", optarg);
    break;
  case 'h':
    // Help need parsing the options here
    break;
  case 'o':
    printf("number of outputs %s\n", optarg);
    break;
  case '?':
    printf("Unknown option: %c\n", optopt);
    break;
  case ':':
    printf("Missing arg for %c\n", optopt);
    break;
  }
}

标签: cgetopt

解决方案


正如评论中所指出的,“getopt”的标准约定是每个选项都有一个值。如果您必须提供该-h 2 5 4 3选项,请考虑以下代码,该代码操纵 optind 以跳过“-h”之后的额外值。

int nLayers = 0 ;
int *layers = NULL ;
while ((opt = getopt(argc, argv, ":d:i:o:h:")) != -1) {
  switch (opt) {
  ...
  case 'h':
    nLayers = atoi(optarg) ;
    layers = calloc(nLayers, sizeof(*layers)) ;
    for (int i=0 ; i<optarg ; i++ ) {
        layers[i] = atoi(argv[optind++]) ;
    } ;
    // Parse Hidden Layers
    break;


  ...
  case ':':
    printf("Missing arg for %c\n", optopt);
    break;
  }
}

请注意,上面的代码不会对数值执行任何检查。

还可以考虑使用“-h 5,4,3”替代“-h 5 -h 4 -h 3”建议,使用 strtok 解析选项值。

int nLayers = 0 ;
int *layers = NULL ;
while ((opt = getopt(argc, argv, ":d:i:o:h:")) != -1) {
  switch (opt) {
  ...
  case 'h':
    // Parse Hidden Layers
    for ( char *p = strtok(optval, ",") ; p != NULL ; p = strtok(NULL, ",") ) {
        nLayers++ ;
        layers = realloc(layers, sizeof(*layers)*nLayers) ;
        layers[nLayers-1] = atoi(p) ;
    } ;
    break;


  ...
  case ':':
    printf("Missing arg for %c\n", optopt);
    break;
  }
}

推荐阅读