getopt系列函数会重新排序argv

getopt这个东西就不多说了,讲这个有点拉低咱水平了。
直接讲重点,GNU在实现getopt等函数的时候做了个个人觉得有点画蛇添足的功能。就是在循环调用时候最后返回-1后会有可能会重新排列argv选项的顺序,他会把“不包含选项的命令行参数”挪到后面去。也就是./a.out -a ima -b host -ckeke -d haha会变成相当于./a.out -a -b host -ckeke -d ima haha的样子
所以如果选项里有一部分需要自己处理的话就没准会变得很恶心。
而optstring最前面加‘+’虽然使得argv不会被重排序,处理方式类同unix,遇到非选项的参数会停止解析,直接返回-1。
所以只得把argv复制出来一份交给getopt糟蹋了。
另外如果需要自己处理的参数排在前面的话也可以使用optind指定从哪个参数开始处理。
测试过程如下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char **argv)
{
    int result;
    opterr = 0; //disable error output
    while( (result = getopt(argc, argv, "ab:c::")) != -1 )
    {
           switch(result)
          {
              case 'a':
                  printf("option=a, optopt=%c, optarg=%s\n", optopt, optarg);
                  break;
              case 'b':
                   printf("option=b, optopt=%c, optarg=%s\n", optopt, optarg);
                   break;
              case 'c':
                  printf("option=c, optopt=%c, optarg=%s\n", optopt, optarg);
                    break;
              case '?':
                    printf("result=?, optopt=%c, optarg=%s\n", optopt, optarg);
                    break;
            default:
                  printf("default, result=%c\n",result);
                  break;
          }
       printf("argv[%d]=%s\n", optind, argv[optind]);
    }
    for(result = 0; result < argc; result++)
             printf("%s ", argv[result]);
    puts("\n");
    return 0;
}
[root@de3eb sheepdog]# ./a.out -a ima -b host -ckeke -d haha
option=a, optopt=, optarg=(null)
argv[2]=ima
option=b, optopt=, optarg=host
argv[5]=-ckeke
option=c, optopt=, optarg=keke
argv[6]=-d
result=?, optopt=d, optarg=(null)
argv[7]=haha
./a.out -a -b host -ckeke -d ima haha

[root@de3eb sheepdog]#
发表评论?

0 条评论。

发表评论


请输入正确的验证码