getopt()函数 - optind不按预期递增/表现

时间:2016-11-01 03:32:47

标签: c command-line

根据我将选项传递给此程序的格式,变量optind将正确递增以反映下一个选项值,或者不会。

如果我使用./cfind -aru,我会得到以下(奇怪的)输出。

optind: 1
aflag detected
optind: 1
optind: 1
rflag detected
optind: 1
optind: 2
uflag detected
optind: 2

请注意,optind不会从aflag增加到rflag,但会从rflag增加到uflag。

但是,当我使用格式./cfind -a -r -u时,我得到以下(预期)输出。

optind: 2
aflag detected
optind: 2
optind: 3
rflag detected
optind: 3
optind: 4
uflag detected
optind: 4

这是我想要的输出。

此功能的代码如下。

#include "cfind.h"
#define OPTLIST "acdirstu" // list of valid options

void ProcOpt(int argc, char *argv[]) {
    int opt = 0; // default value
    opterr = 0; // prevent getopt from passing error message to stderr buffer
    // char *filenm = NULL; // pointer to the path name
    while((opt = getopt(argc, argv, OPTLIST)) != -1) {
        switch (opt) {
            case 'a':
                fprintf(stdout, "optind: %i\n", optind);
                aflag = true;
                assert(aflag == true);
                fprintf(stdout, "aflag detected\n");
                fprintf(stdout, "optind: %i\n", optind);
            break;      
            case 'c':
                fprintf(stdout, "optind: %i\n", optind);
                cflag = true;
                assert(cflag == true);
                fprintf(stdout, "cflag detected\n");
                fprintf(stdout, "optind: %i\n", optind);
            break;      
            case 'd':
                fprintf(stdout, "optind: %i\n", optind);
                dflag = true;
                assert(cflag == true);
                fprintf(stdout, "dflag detected\n");
                fprintf(stdout, "optind: %i\n", optind);
            break;      
            case 'i':
                fprintf(stdout, "optind: %i\n", optind);
                iflag = true;
                assert(iflag == true);
                fprintf(stdout, "iflag detected\n");
                fprintf(stdout, "optind: %i\n", optind);
            break;      
            case 'r':
                fprintf(stdout, "optind: %i\n", optind);
                rflag = true;
                assert(rflag == true);
                fprintf(stdout, "rflag detected\n");
                fprintf(stdout, "optind: %i\n", optind);
            break;      
            case 's':
                fprintf(stdout, "optind: %i\n", optind);
                sflag = true;
                assert(sflag == true);
                fprintf(stdout, "sflag detected\n");
                fprintf(stdout, "optind: %i\n", optind);
            break;      
            case 't':
                fprintf(stdout, "optind: %i\n", optind);
                tflag = true;
                assert(tflag == true);
                fprintf(stdout, "tflag detected\n");
                fprintf(stdout, "optind: %i\n", optind);
            break;      
            case 'u':
                fprintf(stdout, "optind: %i\n", optind);
                uflag = true;
                assert(uflag == true);
                fprintf(stdout, "uflag detected\n");
                fprintf(stdout, "optind: %i\n", optind);        
            break;
            default:
                usage();
        }   
    }   
}

我做错了吗?我是否对getopt()以及它如何增加optind产生了误解?

谢谢。

4 个答案:

答案 0 :(得分:2)

getopt手册页说(强调我的):

  

变量optind是argv中要处理的下一个元素的索引

您的调用选项-aru全部包含在argv[1]中的单个字符串中。

答案 1 :(得分:1)

这个输出看起来对我来说。

optind是要处理的下一个参数的索引。当您将所有选项放在一起时,它们全部位于argv[1],所以optind保持为1,直到您处理了u选项。此时,由于argv[1]中的所有内容都已消耗,optind设置为2。

当选项全部位于argv的单独元素中时,optind始终是要处理的下一个参数的索引。

请参阅http://man7.org/linux/man-pages/man3/getopt.3.html

答案 2 :(得分:0)

将它放在程序的开头,看看发生了什么:

for (int i = 0; i < argc; ++i)
     printf("Param %d: %s\n", i, argv[i]);

答案 3 :(得分:0)

#include <stdio.h> #include <unistd.h>
      extern char *optarg;
      extern int optind;
      int main (int argc, char** argv) {
        int c;
      printf("--------- options: ---------\n");
      while ((c = getopt (argc,argv,"abcd:")) != -1) {
          printf("opt: %c arg %s\n", (char)c, optarg);
      }
      argc -= optind - 1;
      argv += optind - 1; 
      printf("------ remaining args: ------\n");
      for (int i = 1; i < argc; i++) {
      printf("argv[%d] = %s\n", i, argv[i]); 
     } 
    }