看看下面的代码:-
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]){
char ch;
int value;
while((ch = getopt(argc, argv, "n: o"))!=EOF){
switch(ch){
case 'n':
value = atoi(optarg);
fprintf(stdout,"\nParameter n");
//Do something
break;
case 'o':
fprintf(stdout,"\nParameter 0");
//Do something
break;
default:
fprintf(stdout,"\nInvalid!");
}
argc -= optind;
argv += optind;
}
}
当我传递以下参数时
./program -n 123 -o
我得到这个结果
Parameter n
我希望得到这个
Parameter n
Parameter o
为什么getopt()在循环的第二次迭代中不返回下一个参数?
更新
所以代码应该像这样:-
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]){
char ch;
int value;
while((ch = getopt(argc, argv, "n:o"))!=-1){
switch(ch){
case 'n':
value = atoi(optarg);
fprintf(stdout,"Parameter n (%d)\n", value);
//Do something
break;
case 'o':
fprintf(stdout,"Parameter o\n");
//Do something
break;
default:
fprintf(stdout,"Invalid!\n");
break;
}
}
}
答案 0 :(得分:2)
在循环内部,您可以:
argc -= optind;
argv += optind;
那是一场灾难-不要这样做。您可以在循环完成后(一次)使用这些语句,但不能在循环主体中使用这些语句。它强制代码跳过选项。在严重的情况下,它最终可能会尝试解析空指针或环境,而这两者都可能无济于事(并且两者都是未定义的行为,因此是YMMV)。
请注意,您已指定空格为选项之一。这样有人可以写:
./a.out -' ' -n 123 -o
,空格将被视为标志选项(例如-o
)。这可能与您的想法不符。使用"n:o"
,且其中没有空格。
您打印:
fprintf(stdout,"\nParameter 0");
该声明的三个小问题:
0
应该是o
-它们是不同的。fprintf(stdout, …)
而不是printf(…)
是一种惯例。并非完全错误,但不寻常。 POSIX将getopt()
函数定义为在完成选项处理后返回-1
而不返回EOF
。这样一来,它在<unistd.h>
中的声明就不会与EOF
中<stdio.h>
的定义有关。 (“基本原理”部分明确指出: getopt()
函数应返回-1
,而不是EOF
,因此不需要<stdio.h>
。)历史上,系统在getopt()
中声明了<stdio.h>
,但是POSIX将其放置在<unistd.h>
中并说它返回了-1
。
您应在交换机中break;
后面加上一个default:
。这是一项基本的防御性编程措施,即使有人在default:
标签之后添加了另一个case标签,它也可以确保不会掉线。