如何" optind"在C中分配?

时间:2017-10-08 22:21:40

标签: c posix getopt

我正在创建这个问题,因为没有太多关于如何为每个循环分配这个optind。

Man page说:

  

变量optind是argv中要处理的下一个元素的索引。系统将此值初始化为1。

下面,我有一个简单的代码,我来自 Head First C ,代码中我们减去" 选择&# 34;来自" argc "然后我们得到剩余参数的数量,然后我们将用它来打印剩余的参数作为" Ingredients"。

#include <unistd.h>
#include <stdio.h>
int main(int argc, char* argv[]) {
char* delivery = "";
int thick = 0 ;
int count = 0;

char ch;,

for(int i = 0; i < argc;i++){
//This is , to show the whole array and their indexes.
    printf("Argv[%i] = %s\n", i, argv[i]);
}
while((ch = getopt(argc, argv, "d:t")) != -1 ){
    switch(ch) {
        case 'd':
            printf("Optind in case 'd' : %i\n",optind);
            delivery = optarg;
            break;
        case 't':
            printf("Optind in case 't' : %i\n",optind);
            thick = 1;
            break;
        default:
            fprintf(stderr,"Unknown option: '%s'\n", optarg); // optional argument.
            return 1;
    }
}
    argc -= optind;
    argv += optind;
    printf("Optind : %i and Argc after the subctraction : %i\n",optind,argc);
    if(thick)
        puts("Thick crust");
    if(delivery[0]){
        printf("To be delivered %s\n", delivery);
    }

    puts("Ingredients:");
    for(count = 0; count < argc ; count ++){
        puts(argv[count]);
    }
    return 0;
}

因此,在代码的开头,for循环会写入所有数组及其索引以查看差异。

然后我用以下代码运行代码:

./pizzaCode -d now Anchovies Pineapple -t //-t is intentionally at the end

有人告诉我,如果旗帜落到最后,它就不会进入&#39; t&#39;案件,但不知何故,它适用于我的ubuntu。这是我想知道的另一件事,但不是主要问题。

所以输出如下:

Argv[0] = ./pizzaCode
Argv[1] = -d
Argv[2] = now
Argv[3] = Anchovies
Argv[4] = Pineapple
Argv[5] = -t
Optind in case 'd' : 3
Optind in case 't' : 6
Optind : 4 and Argc after the subctraction : 2
Thick crust
To be delivered now
Ingredients:
Anchovies
Pineapple

1-到目前为止一切都很好,问题是如何将argv [0]和argv 1变成凤尾鱼和菠萝?

2-另一个问题是,如果选择成为3,那么&#39; d&#39;?由于&#39; d的索引是1而下一个索引是2。

3-如何在循环后optind成为4?在案件中它是6&#39;

我希望我的问题对你们都清楚,我只是想了解逻辑而不是记住它。 提前谢谢!

1 个答案:

答案 0 :(得分:4)

manpage for Gnu getopt记录了这种非标准的实现:

  

默认情况下,getopt()会在扫描时置换argv的内容,以便最终所有非选区都在最后。

这实际上并不完全正确;扫描完最后一个选项后会发生排列,如您在示例中所见。但效果是一样的; argv被置换,以便非选项结束,并修改optind以索引第一个非选项。

如果你想避免排列,那么getopt按照Posix行事:

  

如果optstring的第一个字符是&#39; +&#39;或者设置了环境变量POSIXLY_CORRECT,然后一旦遇到nonoption参数,选项处理就会停止。

在这种情况下,不会进行排列并保留optind的值。

设置POSIXLY_CORRECT还有其他后果,在各个Gnu实用程序的联机帮助页中随处记录。我的习惯是使用+作为选项字符串的第一个字符(除非我实际上想要非Posix行为),但可以说设置环境变量更具可移植性。

针对您的具体问题:

  1. 为什么argv[0]argv[1]上的非选项参数?

    因为您修改了argv:argv += optind;

  2. 为什么循环处理选项optind中有-d 3?

    因为该选项需要参数。所以 next 参数是now参数之后的参数,它已被处理(通过将指针放入optarg)。

  3. optind如何成为4?

    如上所述,在argv向量置换后,它被修改,以便optind成为第一个&#34;未处理的&#34;的索引。非选项参数。