C - 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"))!=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 on");
//Do something
break;
default:
fprintf(stdout,"Invalid!n");
break;
}
}
}

主要问题

在循环中,您有:

argc -= optind;
argv += optind;

这是一场灾难——不要这样做。 您可以在循环完成后使用这些语句(一次(,但不能在循环正文中使用这些语句。 它强制代码跳过选项;在严重的情况下,它最终可能会尝试解析空指针或环境,这两者都没有帮助(两者都是未定义的行为,所以 YMMV(。

切线问题

请注意,您已指定空白是选项之一。 因此,有人可以写:

./a.out -' ' -n 123 -o

空白将被视为标志选项(如-o(。 这可能不是你想的。 使用不带空格的"n:o"

您打印:

fprintf(stdout,"nParameter 0");

该声明的三个小问题:

  1. 0应该是o的——它们是不同的。
  2. 将换行符放在输出格式的末尾而不是开头(除非您想要双倍行距(。 请注意,在打印换行符之前可能不会生成输出,因此末尾的换行符可确保打印的数据更及时地显示。
  3. 使用fprintf(stdout, …)而不是printf(…)是不常规的。 不完全是错误的,而是不寻常的。

getopt()函数由 POSIX 定义为在完成选项处理时返回-1而不是EOF。 这样,它在<unistd.h>中的声明就与<stdio.h>EOF的定义无关。(基本原理部分明确指出:getopt()函数应返回-1,而不是EOF,因此不需要<stdio.h>历史上,有些系统在<stdio.h>中声明getopt(),但POSIX将其放在<unistd.h>中并说它返回-1

您应该在交换机的default:案例之后包含一个break;。 这是一种基本的防御性编程措施 — 即使有人在default:标签后添加了另一个案例标签,它也能确保不会出错。

最新更新