关于posix:如何在C中分配“ optind”?

How does “optind” get assigned in C?

我正在创建这个问题,因为关于每个循环如何分配此optind的信息并不多。

手册页说:

The variable optind is the index of the next element to be processed in argv. The system initializes this value to 1.

下面,我有一个简单的代码,是从Head First C中获得的,在代码中,我们从" argc"中减去" optind",并获得了剩余参数的数量,然后将其用于打印剩余参数作为"成分"。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#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\
"
, i, argv[i]);
}
while((ch = getopt(argc, argv,"d:t")) != -1 ){
    switch(ch) {
        case 'd':
            printf("Optind in case 'd' : %i\
"
,optind);
            delivery = optarg;
            break;
        case 't':
            printf("Optind in case 't' : %i\
"
,optind);
            thick = 1;
            break;
        default:
            fprintf(stderr,"Unknown option: '%s'\
"
, optarg); // optional argument.
            return 1;
    }
}
    argc -= optind;
    argv += optind;
    printf("Optind : %i and Argc after the subctraction : %i\
"
,optind,argc);
    if(thick)
        puts("Thick crust");
    if(delivery[0]){
        printf("To be delivered %s\
"
, delivery);
    }

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

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

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

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

有人告诉我,如果该标志位于末尾,则不会出现" t"情况,但会以某种方式在我的ubuntu上起作用。我想知道的是另一件事,但不是主要问题。

因此输出如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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]和argv1怎么变成了凤尾鱼和菠萝?

2-还有一个问题是,在'd'情况下optind如何变成3?由于d的索引是1,下一个索引是2。

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

我希望我的问题对大家都清楚,我只是想了解逻辑,而不必记住它。
先感谢您!


Gnu getopt的手册页记录了此非标准实现:

By default, getopt() permutes the contents of argv as it scans, so that eventually all the nonoptions are at the end.

实际上,这不是很正确。如您在示例中所看到的,排列发生在扫描最后一个选项之后。但是效果是一样的。对argv进行了排列,以便非选项位于末尾,并且对optind进行了修改以索引第一个非选项。

如果要避免排列,则getopt的行为与Posix相同:

If the first character of optstring is '+' or the environment variable POSIXLY_CORRECT is set, then option processing stops as soon as a nonoption argument is encountered.

在这种情况下,不会进行任何置换,并且optind的值将保留。

设置POSIXLY_CORRECT还会带来其他后果,在各种Gnu实用程序的手册页中和此处都有记录。我的习惯是使用+作为选项字符串的第一个字符(除非我实际上不希望使用非Posix行为),但是可以说设置环境变量更可移植。

对于您的具体问题:

  • 为什么非选项参数位于argv[0]argv[1]

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

  • 为什么循环处理选项-d中的optind 3?

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

  • optind如何变成4?

    如上所述,在对argv向量进行排列后对其进行了修改,以使optind成为第一个"未处理的"非选项参数的索引。