“optind”如何在C中分配?

And*_*hai 3 c posix getopt

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

手册页说:

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

下面,我有一个从Head First C得到的简单代码,在代码中我们从“ argc ”中减去optind ”,我们得到剩余参数的数量,然后我们将使用它来将剩余参数打印为“成分”。

#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;
}
Run Code Online (Sandbox Code Playgroud)

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

然后我运行代码:

./pizzaCode -d now Anchovies Pineapple -t //-t is intentionally at the end
Run Code Online (Sandbox Code Playgroud)

有人告诉我,如果标志在最后,它就不会出现在“不是”的情况下,但不知何故它可以在我的 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
Run Code Online (Sandbox Code Playgroud)

1- 到目前为止一切都很好,问题是 argv[0] 和 argv 1怎么变成 Anchovies 和 Pineapple 了?

2-另一个问题是,如果'd',optind是如何变成3的?因为 'd 的索引是 1,下一个索引是 2。

3- 循环后 optind 是如何变成 4 的?在“t”的情况下是 6。

我希望我的问题对你们来说很清楚,我只是想理解逻辑而不是记住它。先感谢您!

ric*_*ici 7

Gnugetopt联机帮助页记录了这个非标准实现:

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

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

如果您想避免排列,则其getopt行为与 Posix 相同:

如果 optstring 的第一个字符是 '+' 或POSIXLY_CORRECT设置了环境变量,则一旦遇到非选项参数,选项处理就会停止。

在这种情况下,不进行任何排列并且optind保留了 的值。

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


对于您的具体问题:

  1. 为什么非选项参数在argv[0]argv[1]

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

  2. 为什么optind循环处理选项是3 -d

    因为那个选项需要一个参数。因此,下一个参数是该参数之后的now参数,该参数已被处理(通过将指向它的指针放入optarg)。

  3. 怎么optind变成4了?

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