"optind" 如何在 C 中分配?
How does "optind" get assigned in C?
我提出这个问题是因为没有太多关于如何为每个循环分配这个 optind。
Man page 说:
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 获得的简单代码,在代码中我们 subtract " optind" 来自 "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
有人告诉我,如果标志在末尾,它就不会出现在 't' 的情况下,但不知何故它在我的 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] 和 argv1 怎么变成凤尾鱼和菠萝了?
2- 另一个问题是在 'd' 的情况下 optind 是如何变成 3 的?由于'd's索引为1,下一个索引为2。
3-循环后optind是怎么变成4的?在 't'.
的情况下是 6
我希望你们都清楚我的问题,我只是想理解逻辑而不是必须记住它。
提前致谢!
manpage for 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;
为什么循环处理选项optind
3是-d
?
因为该选项需要一个参数。所以 next 参数是 now
参数之后的参数,它已经被处理(通过将指向它的指针放入 optarg
)。
optind
是怎么变成4的?
如上,在 argv
向量排列后修改,以便 optind
成为第一个 "unprocessed" 非选项参数的索引。
我提出这个问题是因为没有太多关于如何为每个循环分配这个 optind。
Man page 说:
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 获得的简单代码,在代码中我们 subtract " optind" 来自 "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
有人告诉我,如果标志在末尾,它就不会出现在 't' 的情况下,但不知何故它在我的 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] 和 argv1 怎么变成凤尾鱼和菠萝了?
2- 另一个问题是在 'd' 的情况下 optind 是如何变成 3 的?由于'd's索引为1,下一个索引为2。
3-循环后optind是怎么变成4的?在 't'.
的情况下是 6我希望你们都清楚我的问题,我只是想理解逻辑而不是必须记住它。 提前致谢!
manpage for Gnu getopt
记录了这个非标准的实现:
By default,
getopt()
permutes the contents ofargv
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;
为什么循环处理选项
optind
3是-d
?因为该选项需要一个参数。所以 next 参数是
now
参数之后的参数,它已经被处理(通过将指向它的指针放入optarg
)。optind
是怎么变成4的?如上,在
argv
向量排列后修改,以便optind
成为第一个 "unprocessed" 非选项参数的索引。